diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index e9facd697de..4f8ddad33d1 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -38,7 +38,6 @@ jobs: - "8.3" dbal-version: - "default" - - "3.7" extension: - "sqlite3" - "pdo_sqlite" @@ -109,7 +108,6 @@ jobs: - "8.3" dbal-version: - "default" - - "3.7" postgres-version: - "15" extension: @@ -121,8 +119,8 @@ jobs: postgres-version: "14" extension: pdo_pgsql - php-version: "8.2" - dbal-version: "3.7" - postgres-version: "9.6" + dbal-version: "default" + postgres-version: "10" extension: pdo_pgsql services: @@ -182,7 +180,6 @@ jobs: - "8.3" dbal-version: - "default" - - "3.7" - "4@dev" mariadb-version: - "10.9" @@ -248,7 +245,6 @@ jobs: - "8.3" dbal-version: - "default" - - "3.7" mysql-version: - "5.7" - "8.0" diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml index 5082f75051d..e3632eddd09 100644 --- a/.github/workflows/static-analysis.yml +++ b/.github/workflows/static-analysis.yml @@ -27,14 +27,6 @@ jobs: name: Static Analysis with PHPStan runs-on: ubuntu-22.04 - strategy: - matrix: - include: - - dbal-version: default - config: phpstan.neon - - dbal-version: 3.8.2 - config: phpstan-dbal3.neon - steps: - name: "Checkout code" uses: "actions/checkout@v4" @@ -46,27 +38,16 @@ jobs: php-version: "8.3" tools: cs2pr - - name: Require specific DBAL version - run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update" - if: "${{ matrix.dbal-version != 'default' }}" - - - name: Install dependencies with Composer uses: ramsey/composer-install@v2 - name: Run static analysis with phpstan/phpstan - run: "vendor/bin/phpstan analyse -c ${{ matrix.config }} --error-format=checkstyle | cs2pr" + run: "vendor/bin/phpstan analyse --error-format=checkstyle | cs2pr" static-analysis-psalm: name: Static Analysis with Psalm runs-on: ubuntu-22.04 - strategy: - matrix: - dbal-version: - - default - - 3.8.2 - steps: - name: "Checkout code" uses: "actions/checkout@v4" @@ -76,11 +57,6 @@ jobs: with: coverage: none php-version: "8.3" - tools: cs2pr - - - name: Require specific DBAL version - run: "composer require doctrine/dbal ^${{ matrix.dbal-version }} --no-update" - if: "${{ matrix.dbal-version != 'default' }}" - name: Install dependencies with Composer uses: ramsey/composer-install@v2 diff --git a/composer.json b/composer.json index 1a42c2c3ab8..ff6ded34780 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "composer-runtime-api": "^2", "ext-ctype": "*", "doctrine/collections": "^2.2", - "doctrine/dbal": "^3.8.2 || ^4", + "doctrine/dbal": "^4", "doctrine/deprecations": "^0.5.3 || ^1", "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", diff --git a/phpstan-dbal3.neon b/phpstan-dbal3.neon deleted file mode 100644 index a223cd4b792..00000000000 --- a/phpstan-dbal3.neon +++ /dev/null @@ -1,33 +0,0 @@ -includes: - - phpstan-baseline.neon - - phpstan-params.neon - -parameters: - ignoreErrors: - # Symfony cache supports passing a key prefix to the clear method. - - '/^Method Psr\\Cache\\CacheItemPoolInterface\:\:clear\(\) invoked with 1 parameter, 0 required\.$/' - - # We can be certain that those values are not matched. - - - message: '~^Match expression does not handle remaining values:~' - path: src/Persisters/Entity/BasicEntityPersister.php - - # DBAL 4 compatibility - - - message: '~^Method Doctrine\\ORM\\Query\\AST\\Functions\\TrimFunction::getTrimMode\(\) never returns .* so it can be removed from the return type\.$~' - path: src/Query/AST/Functions/TrimFunction.php - - - message: '~^Method Doctrine\\ORM\\Persisters\\Entity\\BasicEntityPersister\:\:getArrayBindingType\(\) never returns .* so it can be removed from the return type\.$~' - path: src/Persisters/Entity/BasicEntityPersister.php - - - - message: '~^Unreachable statement \- code above always terminates\.$~' - path: src/Mapping/AssociationMapping.php - - - '~^Class Doctrine\\DBAL\\Platforms\\SQLitePlatform not found\.$~' - - # To be removed in 4.0 - - - message: '#Negated boolean expression is always false\.#' - paths: - - src/Mapping/Driver/AttributeDriver.php diff --git a/phpstan.neon b/phpstan.neon index 4ea0a3630a2..2820661ef62 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -12,39 +12,11 @@ parameters: message: '~^Match expression does not handle remaining values:~' path: src/Persisters/Entity/BasicEntityPersister.php - # DBAL 4 compatibility - - - message: '~^Method Doctrine\\ORM\\Query\\AST\\Functions\\TrimFunction::getTrimMode\(\) never returns .* so it can be removed from the return type\.$~' - path: src/Query/AST/Functions/TrimFunction.php - - - message: '~^Method Doctrine\\ORM\\Persisters\\Entity\\BasicEntityPersister\:\:getArrayBindingType\(\) never returns .* so it can be removed from the return type\.$~' - path: src/Persisters/Entity/BasicEntityPersister.php - + # To be removed in 4.0 - message: '~^Unreachable statement \- code above always terminates\.$~' path: src/Mapping/AssociationMapping.php - # Compatibility with DBAL 3 - # See https://github.com/doctrine/dbal/pull/3480 - - - message: '~^Result of method Doctrine\\DBAL\\Connection::commit\(\) \(void\) is used\.$~' - path: src/UnitOfWork.php - - - message: '~^Strict comparison using === between null and false will always evaluate to false\.$~' - path: src/UnitOfWork.php - - - message: '~^Variable \$e on left side of \?\? always exists and is not nullable\.$~' - path: src/UnitOfWork.php - - - - message: '~^Parameter #1 \$command of method Symfony\\Component\\Console\\Application::add\(\) expects Symfony\\Component\\Console\\Command\\Command, Doctrine\\DBAL\\Tools\\Console\\Command\\ReservedWordsCommand given\.$~' - path: src/Tools/Console/ConsoleRunner.php - - - - message: '~Strict comparison using \=\=\= between callable\(\)\: mixed and null will always evaluate to false\.~' - path: src/Tools/SchemaTool.php - - # To be removed in 4.0 - message: '#Negated boolean expression is always false\.#' paths: diff --git a/psalm-baseline.xml b/psalm-baseline.xml index ccb9a965194..7b605c88fde 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -861,9 +861,6 @@ - - - diff --git a/psalm.xml b/psalm.xml index 3b27be7f8e2..d5c3d090ddf 100644 --- a/psalm.xml +++ b/psalm.xml @@ -24,8 +24,6 @@ - - @@ -45,22 +43,11 @@ - - - - - - - - - - - @@ -183,43 +170,13 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/AbstractQuery.php b/src/AbstractQuery.php index 0ff92c30089..f4f3839c539 100644 --- a/src/AbstractQuery.php +++ b/src/AbstractQuery.php @@ -321,16 +321,16 @@ public function setParameters(ArrayCollection|array $parameters): static /** * Sets a query parameter. * - * @param string|int $key The parameter position or name. - * @param mixed $value The parameter value. - * @param ParameterType|ArrayParameterType|string|int|null $type The parameter type. If specified, the given value - * will be run through the type conversion of this - * type. This is usually not needed for strings and - * numeric types. + * @param string|int $key The parameter position or name. + * @param mixed $value The parameter value. + * @param ParameterType|ArrayParameterType|string|null $type The parameter type. If specified, the given value + * will be run through the type conversion of this + * type. This is usually not needed for strings and + * numeric types. * * @return $this */ - public function setParameter(string|int $key, mixed $value, ParameterType|ArrayParameterType|string|int|null $type = null): static + public function setParameter(string|int $key, mixed $value, ParameterType|ArrayParameterType|string|null $type = null): static { $existingParameter = $this->getParameter($key); diff --git a/src/Cache/Persister/Entity/AbstractEntityPersister.php b/src/Cache/Persister/Entity/AbstractEntityPersister.php index 9f371d8b205..cbdc50054a7 100644 --- a/src/Cache/Persister/Entity/AbstractEntityPersister.php +++ b/src/Cache/Persister/Entity/AbstractEntityPersister.php @@ -90,7 +90,7 @@ public function getInserts(): array public function getSelectSQL( array|Criteria $criteria, AssociationMapping|null $assoc = null, - LockMode|int|null $lockMode = null, + LockMode|null $lockMode = null, int|null $limit = null, int|null $offset = null, array|null $orderBy = null, @@ -290,7 +290,7 @@ public function load( object|null $entity = null, AssociationMapping|null $assoc = null, array $hints = [], - LockMode|int|null $lockMode = null, + LockMode|null $lockMode = null, int|null $limit = null, array|null $orderBy = null, ): object|null { @@ -533,7 +533,7 @@ public function loadOneToOneEntity(AssociationMapping $assoc, object $sourceEnti /** * {@inheritDoc} */ - public function lock(array $criteria, LockMode|int $lockMode): void + public function lock(array $criteria, LockMode $lockMode): void { $this->persister->lock($criteria, $lockMode); } @@ -541,7 +541,7 @@ public function lock(array $criteria, LockMode|int $lockMode): void /** * {@inheritDoc} */ - public function refresh(array $id, object $entity, LockMode|int|null $lockMode = null): void + public function refresh(array $id, object $entity, LockMode|null $lockMode = null): void { $this->persister->refresh($id, $entity, $lockMode); } diff --git a/src/Decorator/EntityManagerDecorator.php b/src/Decorator/EntityManagerDecorator.php index 6f1b0419686..0e0c0cfa262 100644 --- a/src/Decorator/EntityManagerDecorator.php +++ b/src/Decorator/EntityManagerDecorator.php @@ -107,17 +107,17 @@ public function close(): void $this->wrapped->close(); } - public function lock(object $entity, LockMode|int $lockMode, DateTimeInterface|int|null $lockVersion = null): void + public function lock(object $entity, LockMode $lockMode, DateTimeInterface|int|null $lockVersion = null): void { $this->wrapped->lock($entity, $lockMode, $lockVersion); } - public function find(string $className, mixed $id, LockMode|int|null $lockMode = null, int|null $lockVersion = null): object|null + public function find(string $className, mixed $id, LockMode|null $lockMode = null, int|null $lockVersion = null): object|null { return $this->wrapped->find($className, $id, $lockMode, $lockVersion); } - public function refresh(object $object, LockMode|int|null $lockMode = null): void + public function refresh(object $object, LockMode|null $lockMode = null): void { $this->wrapped->refresh($object, $lockMode); } diff --git a/src/EntityManager.php b/src/EntityManager.php index bb9e2ad2ced..86aa1d0d5b1 100644 --- a/src/EntityManager.php +++ b/src/EntityManager.php @@ -30,7 +30,6 @@ use function is_array; use function is_object; use function ltrim; -use function method_exists; /** * The EntityManager is the central access point to ORM functionality. @@ -120,11 +119,7 @@ public function __construct( throw MissingMappingDriverImplementation::create(); } - $this->eventManager = $eventManager - ?? (method_exists($conn, 'getEventManager') - ? $conn->getEventManager() - : new EventManager() - ); + $this->eventManager = $eventManager ?? new EventManager(); $metadataFactoryClassName = $config->getClassMetadataFactoryName(); @@ -262,7 +257,7 @@ public function flush(): void /** * {@inheritDoc} */ - public function find($className, mixed $id, LockMode|int|null $lockMode = null, int|null $lockVersion = null): object|null + public function find($className, mixed $id, LockMode|null $lockMode = null, int|null $lockVersion = null): object|null { $class = $this->metadataFactory->getMetadataFor(ltrim($className, '\\')); @@ -450,7 +445,7 @@ public function remove(object $object): void $this->unitOfWork->remove($object); } - public function refresh(object $object, LockMode|int|null $lockMode = null): void + public function refresh(object $object, LockMode|null $lockMode = null): void { $this->errorIfClosed(); @@ -471,7 +466,7 @@ public function detach(object $object): void $this->unitOfWork->detach($object); } - public function lock(object $entity, LockMode|int $lockMode, DateTimeInterface|int|null $lockVersion = null): void + public function lock(object $entity, LockMode $lockMode, DateTimeInterface|int|null $lockVersion = null): void { $this->unitOfWork->lock($entity, $lockMode, $lockVersion); } @@ -581,12 +576,10 @@ public function hasFilters(): bool } /** - * @psalm-param LockMode::* $lockMode - * * @throws OptimisticLockException * @throws TransactionRequiredException */ - private function checkLockRequirements(LockMode|int $lockMode, ClassMetadata $class): void + private function checkLockRequirements(LockMode $lockMode, ClassMetadata $class): void { switch ($lockMode) { case LockMode::OPTIMISTIC: diff --git a/src/EntityManagerInterface.php b/src/EntityManagerInterface.php index 3f5535233f9..f9bd127ead9 100644 --- a/src/EntityManagerInterface.php +++ b/src/EntityManagerInterface.php @@ -110,15 +110,13 @@ public function createQueryBuilder(): QueryBuilder; /** * Finds an Entity by its identifier. * - * @param string $className The class name of the entity to find. - * @param mixed $id The identity of the entity to find. - * @param LockMode|int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants - * or NULL if no specific lock mode should be used - * during the search. - * @param int|null $lockVersion The version of the entity to find when using - * optimistic locking. + * @param string $className The class name of the entity to find. + * @param mixed $id The identity of the entity to find. + * @param LockMode|null $lockMode The lock mode or NULL if no specific lock mode + * should be used during the search. + * @param int|null $lockVersion The version of the entity to find when using + * optimistic locking. * @psalm-param class-string $className - * @psalm-param LockMode::*|null $lockMode * * @return object|null The entity instance or NULL if the entity can not be found. * @psalm-return T|null @@ -130,22 +128,20 @@ public function createQueryBuilder(): QueryBuilder; * * @template T of object */ - public function find(string $className, mixed $id, LockMode|int|null $lockMode = null, int|null $lockVersion = null): object|null; + public function find(string $className, mixed $id, LockMode|null $lockMode = null, int|null $lockVersion = null): object|null; /** * Refreshes the persistent state of an object from the database, * overriding any local changes that have not yet been persisted. * - * @param LockMode|int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants - * or NULL if no specific lock mode should be used - * during the search. - * @psalm-param LockMode::*|null $lockMode + * @param LockMode|null $lockMode The lock mode or NULL if no specific lock mode + * should be used during the search. * * @throws ORMInvalidArgumentException * @throws ORMException * @throws TransactionRequiredException */ - public function refresh(object $object, LockMode|int|null $lockMode = null): void; + public function refresh(object $object, LockMode|null $lockMode = null): void; /** * Gets a reference to the entity identified by the given type and identifier @@ -173,12 +169,10 @@ public function close(): void; /** * Acquire a lock on the given entity. * - * @psalm-param LockMode::* $lockMode - * * @throws OptimisticLockException * @throws PessimisticLockException */ - public function lock(object $entity, LockMode|int $lockMode, DateTimeInterface|int|null $lockVersion = null): void; + public function lock(object $entity, LockMode $lockMode, DateTimeInterface|int|null $lockVersion = null): void; /** * Gets the EventManager used by the EntityManager. diff --git a/src/EntityRepository.php b/src/EntityRepository.php index a53c5284881..38d7fcbe112 100644 --- a/src/EntityRepository.php +++ b/src/EntityRepository.php @@ -73,15 +73,13 @@ public function createResultSetMappingBuilder(string $alias): ResultSetMappingBu /** * Finds an entity by its primary key / identifier. * - * @param LockMode|int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants - * or NULL if no specific lock mode should be used - * during the search. - * @psalm-param LockMode::*|null $lockMode + * @param LockMode|null $lockMode The lock mode or NULL if no specific lock mode + * should be used during the search. * * @return object|null The entity instance or NULL if the entity can not be found. * @psalm-return ?T */ - public function find(mixed $id, LockMode|int|null $lockMode = null, int|null $lockVersion = null): object|null + public function find(mixed $id, LockMode|null $lockMode = null, int|null $lockVersion = null): object|null { return $this->em->find($this->entityName, $id, $lockMode, $lockVersion); } diff --git a/src/Mapping/ClassMetadataFactory.php b/src/Mapping/ClassMetadataFactory.php index a3a47018081..99890e38b70 100644 --- a/src/Mapping/ClassMetadataFactory.php +++ b/src/Mapping/ClassMetadataFactory.php @@ -7,7 +7,6 @@ use Doctrine\Common\EventManager; use Doctrine\DBAL\Platforms; use Doctrine\DBAL\Platforms\AbstractPlatform; -use Doctrine\Deprecations\Deprecation; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\Event\LoadClassMetadataEventArgs; use Doctrine\ORM\Event\OnClassMetadataNotFoundEventArgs; @@ -35,7 +34,6 @@ use function in_array; use function is_a; use function is_subclass_of; -use function method_exists; use function str_contains; use function strlen; use function strtolower; @@ -622,39 +620,8 @@ private function determineIdGeneratorStrategy(AbstractPlatform $platform): int } } - $nonIdentityDefaultStrategy = self::NON_IDENTITY_DEFAULT_STRATEGY; - - // DBAL 3 - if (method_exists($platform, 'getIdentitySequenceName')) { - $nonIdentityDefaultStrategy[Platforms\PostgreSQLPlatform::class] = ClassMetadata::GENERATOR_TYPE_SEQUENCE; - } - - foreach ($nonIdentityDefaultStrategy as $platformFamily => $strategy) { + foreach (self::NON_IDENTITY_DEFAULT_STRATEGY as $platformFamily => $strategy) { if (is_a($platform, $platformFamily)) { - if ($platform instanceof Platforms\PostgreSQLPlatform) { - Deprecation::trigger( - 'doctrine/orm', - 'https://github.com/doctrine/orm/issues/8893', - <<<'DEPRECATION' - Relying on non-optimal defaults for ID generation is deprecated, and IDENTITY - results in SERIAL, which is not recommended. - Instead, configure identifier generation strategies explicitly through - configuration. - We currently recommend "SEQUENCE" for "%s", when using DBAL 3, - and "IDENTITY" when using DBAL 4, - so you should probably use the following configuration before upgrading to DBAL 4, - and remove it after deploying that upgrade: - - $configuration->setIdentityGenerationPreferences([ - "%s" => ClassMetadata::GENERATOR_TYPE_SEQUENCE, - ]); - - DEPRECATION, - $platformFamily, - $platformFamily, - ); - } - return $strategy; } } diff --git a/src/Mapping/Driver/DatabaseDriver.php b/src/Mapping/Driver/DatabaseDriver.php index 49e2e93520c..4c09e2b01c9 100644 --- a/src/Mapping/Driver/DatabaseDriver.php +++ b/src/Mapping/Driver/DatabaseDriver.php @@ -39,20 +39,6 @@ */ class DatabaseDriver implements MappingDriver { - /** - * Replacement for {@see Types::ARRAY}. - * - * To be removed as soon as support for DBAL 3 is dropped. - */ - private const ARRAY = 'array'; - - /** - * Replacement for {@see Types::OBJECT}. - * - * To be removed as soon as support for DBAL 3 is dropped. - */ - private const OBJECT = 'object'; - /** @var array|null */ private array|null $tables = null; @@ -394,10 +380,8 @@ private function buildFieldMapping(string $tableName, Column $column): array // Type specific elements switch ($fieldMapping['type']) { - case self::ARRAY: case Types::BLOB: case Types::GUID: - case self::OBJECT: case Types::SIMPLE_ARRAY: case Types::STRING: case Types::TEXT: diff --git a/src/Persisters/Entity/BasicEntityPersister.php b/src/Persisters/Entity/BasicEntityPersister.php index 377e03ce274..3a06aea01a3 100644 --- a/src/Persisters/Entity/BasicEntityPersister.php +++ b/src/Persisters/Entity/BasicEntityPersister.php @@ -339,8 +339,7 @@ protected function fetchVersionAndNotUpsertableValues(ClassMetadata $versionedCl /** * @param mixed[] $id * - * @return list - * @psalm-return list + * @return list */ final protected function extractIdentifierTypes(array $id, ClassMetadata $versionedClass): array { @@ -723,7 +722,7 @@ public function load( object|null $entity = null, AssociationMapping|null $assoc = null, array $hints = [], - LockMode|int|null $lockMode = null, + LockMode|null $lockMode = null, int|null $limit = null, array|null $orderBy = null, ): object|null { @@ -817,7 +816,7 @@ public function loadOneToOneEntity(AssociationMapping $assoc, object $sourceEnti /** * {@inheritDoc} */ - public function refresh(array $id, object $entity, LockMode|int|null $lockMode = null): void + public function refresh(array $id, object $entity, LockMode|null $lockMode = null): void { $sql = $this->getSelectSQL($id, null, $lockMode); [$params, $types] = $this->expandParameters($id); @@ -1054,7 +1053,7 @@ private function getManyToManyStatement( public function getSelectSQL( array|Criteria $criteria, AssociationMapping|null $assoc = null, - LockMode|int|null $lockMode = null, + LockMode|null $lockMode = null, int|null $limit = null, int|null $offset = null, array|null $orderBy = null, @@ -1507,7 +1506,7 @@ protected function getSQLTableAlias(string $className, string $assocName = ''): /** * {@inheritDoc} */ - public function lock(array $criteria, LockMode|int $lockMode): void + public function lock(array $criteria, LockMode $lockMode): void { $conditionSql = $this->getSelectConditionSQL($criteria); @@ -1531,10 +1530,8 @@ public function lock(array $criteria, LockMode|int $lockMode): void /** * Gets the FROM and optionally JOIN conditions to lock the entity managed by this persister. - * - * @psalm-param LockMode::* $lockMode */ - protected function getLockTablesSql(LockMode|int $lockMode): string + protected function getLockTablesSql(LockMode $lockMode): string { return $this->platform->appendLockHint( 'FROM ' @@ -1833,7 +1830,7 @@ public function expandParameters(array $criteria): array * - class to which the field belongs to * * @return mixed[][] - * @psalm-return array{0: array, 1: list} + * @psalm-return array{0: array, 1: list} */ private function expandToManyParameters(array $criteria): array { @@ -1855,8 +1852,7 @@ private function expandToManyParameters(array $criteria): array /** * Infers field types to be used by parameter type casting. * - * @return list - * @psalm-return list + * @return list * * @throws QueryException */ @@ -1898,11 +1894,10 @@ private function getTypes(string $field, mixed $value, ClassMetadata $class): ar return $types; } - /** @psalm-return ArrayParameterType::* */ - private function getArrayBindingType(ParameterType|int|string $type): ArrayParameterType|int + private function getArrayBindingType(ParameterType|string $type): ArrayParameterType { if (! $type instanceof ParameterType) { - $type = Type::getType((string) $type)->getBindingType(); + $type = Type::getType($type)->getBindingType(); } return match ($type) { diff --git a/src/Persisters/Entity/EntityPersister.php b/src/Persisters/Entity/EntityPersister.php index 6b278a711d0..e0a78836643 100644 --- a/src/Persisters/Entity/EntityPersister.php +++ b/src/Persisters/Entity/EntityPersister.php @@ -48,12 +48,11 @@ public function getInsertSQL(): string; * @param mixed[]|Criteria $criteria * @param mixed[]|null $orderBy * @psalm-param AssociationMapping|null $assoc - * @psalm-param LockMode::*|null $lockMode */ public function getSelectSQL( array|Criteria $criteria, AssociationMapping|null $assoc = null, - LockMode|int|null $lockMode = null, + LockMode|null $lockMode = null, int|null $limit = null, int|null $offset = null, array|null $orderBy = null, @@ -71,14 +70,14 @@ public function getCountSQL(array|Criteria $criteria = []): string; * * @param string[] $criteria * - * @psalm-return array{list, list} + * @psalm-return array{list, list} */ public function expandParameters(array $criteria): array; /** * Expands Criteria Parameters by walking the expressions and grabbing all parameters and types from it. * - * @psalm-return array{list, list} + * @psalm-return array{list, list} */ public function expandCriteriaParameters(Criteria $criteria): array; @@ -146,14 +145,12 @@ public function getOwningTable(string $fieldName): string; * @param AssociationMapping|null $assoc The association that connects the entity * to load to another entity, if any. * @param mixed[] $hints Hints for entity creation. - * @param LockMode|int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants - * or NULL if no specific lock mode should be used - * for loading the entity. + * @param LockMode|null $lockMode The lock mode or NULL if no specific lock mode + * should be used for loading the entity. * @param int|null $limit Limit number of results. * @param string[]|null $orderBy Criteria to order by. * @psalm-param array $criteria * @psalm-param array $hints - * @psalm-param LockMode::*|null $lockMode * @psalm-param array|null $orderBy * * @return object|null The loaded and managed entity instance or NULL if the entity can not be found. @@ -165,7 +162,7 @@ public function load( object|null $entity = null, AssociationMapping|null $assoc = null, array $hints = [], - LockMode|int|null $lockMode = null, + LockMode|null $lockMode = null, int|null $limit = null, array|null $orderBy = null, ): object|null; @@ -201,15 +198,13 @@ public function loadOneToOneEntity(AssociationMapping $assoc, object $sourceEnti /** * Refreshes a managed entity. * - * @param LockMode|int|null $lockMode One of the \Doctrine\DBAL\LockMode::* constants - * or NULL if no specific lock mode should be used - * for refreshing the managed entity. + * @param LockMode|null $lockMode The lock mode or NULL if no specific lock mode + * should be used for refreshing the managed entity. * @psalm-param array $id The identifier of the entity as an * associative array from column or * field names to values. - * @psalm-param LockMode::*|null $lockMode */ - public function refresh(array $id, object $entity, LockMode|int|null $lockMode = null): void; + public function refresh(array $id, object $entity, LockMode|null $lockMode = null): void; /** * Loads Entities matching the given Criteria object. @@ -275,9 +270,8 @@ public function loadOneToManyCollection( * Locks all rows of this entity matching the given criteria with the specified pessimistic lock mode. * * @psalm-param array $criteria - * @psalm-param LockMode::* $lockMode */ - public function lock(array $criteria, LockMode|int $lockMode): void; + public function lock(array $criteria, LockMode $lockMode): void; /** * Returns an array with (sliced or full list) of elements in the specified collection. diff --git a/src/Persisters/Entity/JoinedSubclassPersister.php b/src/Persisters/Entity/JoinedSubclassPersister.php index 76719a2c275..f42d4533ab6 100644 --- a/src/Persisters/Entity/JoinedSubclassPersister.php +++ b/src/Persisters/Entity/JoinedSubclassPersister.php @@ -238,7 +238,7 @@ public function delete(object $entity): bool public function getSelectSQL( array|Criteria $criteria, AssociationMapping|null $assoc = null, - LockMode|int|null $lockMode = null, + LockMode|null $lockMode = null, int|null $limit = null, int|null $offset = null, array|null $orderBy = null, @@ -329,7 +329,7 @@ public function getCountSQL(array|Criteria $criteria = []): string . (empty($conditionSql) ? '' : ' WHERE ' . $conditionSql); } - protected function getLockTablesSql(LockMode|int $lockMode): string + protected function getLockTablesSql(LockMode $lockMode): string { $joinSql = ''; $identifierColumns = $this->class->getIdentifierColumnNames(); diff --git a/src/Query.php b/src/Query.php index 5b0ceb7a97c..65910fddd2c 100644 --- a/src/Query.php +++ b/src/Query.php @@ -613,13 +613,11 @@ public function setHydrationMode(string|int $hydrationMode): static * * @see \Doctrine\DBAL\LockMode * - * @psalm-param LockMode::* $lockMode - * * @return $this * * @throws TransactionRequiredException */ - public function setLockMode(LockMode|int $lockMode): self + public function setLockMode(LockMode $lockMode): self { if (in_array($lockMode, [LockMode::NONE, LockMode::PESSIMISTIC_READ, LockMode::PESSIMISTIC_WRITE], true)) { if (! $this->em->getConnection()->isTransactionActive()) { @@ -635,9 +633,9 @@ public function setLockMode(LockMode|int $lockMode): self /** * Get the current lock mode for this query. * - * @return int|null The current lock mode of this query or NULL if no specific lock mode is set. + * @return LockMode|null The current lock mode of this query or NULL if no specific lock mode is set. */ - public function getLockMode(): int|null + public function getLockMode(): LockMode|null { $lockMode = $this->getHint(self::HINT_LOCK_MODE); diff --git a/src/Query/AST/Functions/TrimFunction.php b/src/Query/AST/Functions/TrimFunction.php index e0a3e99c356..9b50641993b 100644 --- a/src/Query/AST/Functions/TrimFunction.php +++ b/src/Query/AST/Functions/TrimFunction.php @@ -68,8 +68,7 @@ public function parse(Parser $parser): void $parser->match(TokenType::T_CLOSE_PARENTHESIS); } - /** @psalm-return TrimMode::* */ - private function getTrimMode(): TrimMode|int + private function getTrimMode(): TrimMode { if ($this->leading) { return TrimMode::LEADING; diff --git a/src/Query/Exec/AbstractSqlExecutor.php b/src/Query/Exec/AbstractSqlExecutor.php index 101bf266cf8..e7baf3721a6 100644 --- a/src/Query/Exec/AbstractSqlExecutor.php +++ b/src/Query/Exec/AbstractSqlExecutor.php @@ -17,7 +17,7 @@ * @link http://www.doctrine-project.org * * @todo Rename: AbstractSQLExecutor - * @psalm-type WrapperParameterType = string|Type|ParameterType::*|ArrayParameterType::* + * @psalm-type WrapperParameterType = string|Type|ParameterType|ArrayParameterType * @psalm-type WrapperParameterTypeArray = array, WrapperParameterType>|array */ abstract class AbstractSqlExecutor diff --git a/src/Query/ParameterTypeInferer.php b/src/Query/ParameterTypeInferer.php index dae28faee18..7b672971702 100644 --- a/src/Query/ParameterTypeInferer.php +++ b/src/Query/ParameterTypeInferer.php @@ -25,11 +25,12 @@ final class ParameterTypeInferer { /** - * Infers type of a given value, returning a compatible constant: + * Infers type of a given value, returning a compatible constant or enum case: * - Type (\Doctrine\DBAL\Types\Type::*) - * - Connection (\Doctrine\DBAL\Connection::PARAM_*) + * - ParameterType (\Doctrine\DBAL\ParameterType) + * - ArrayParameterType (\Doctrine\DBAL\ArrayParameterType) */ - public static function inferType(mixed $value): ParameterType|ArrayParameterType|int|string + public static function inferType(mixed $value): ParameterType|ArrayParameterType|string { if (is_int($value)) { return Types::INTEGER; diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index a6a39a964b8..13f54f7f84d 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -433,12 +433,12 @@ public function getRootEntities(): array * ->setParameter('user_id', 1); * * - * @param string|int $key The parameter position or name. - * @param ParameterType|ArrayParameterType|string|int|null $type ParameterType::*, ArrayParameterType::* or \Doctrine\DBAL\Types\Type::* constant + * @param string|int $key The parameter position or name. + * @param ParameterType|ArrayParameterType|string|null $type ParameterType::*, ArrayParameterType::* or \Doctrine\DBAL\Types\Type::* constant * * @return $this */ - public function setParameter(string|int $key, mixed $value, ParameterType|ArrayParameterType|string|int|null $type = null): static + public function setParameter(string|int $key, mixed $value, ParameterType|ArrayParameterType|string|null $type = null): static { $existingParameter = $this->getParameter($key); diff --git a/src/Tools/Console/ConsoleRunner.php b/src/Tools/Console/ConsoleRunner.php index 0a00483244e..f60f0f07709 100644 --- a/src/Tools/Console/ConsoleRunner.php +++ b/src/Tools/Console/ConsoleRunner.php @@ -12,7 +12,6 @@ use Symfony\Component\Console\Command\Command as SymfonyCommand; use function assert; -use function class_exists; /** * Handles running the Console Tools inside Symfony Console context. @@ -58,10 +57,6 @@ public static function addCommands(Application $cli, EntityManagerProvider $enti { $connectionProvider = new ConnectionFromManagerProvider($entityManagerProvider); - if (class_exists(DBALConsole\Command\ReservedWordsCommand::class)) { - $cli->add(new DBALConsole\Command\ReservedWordsCommand($connectionProvider)); - } - $cli->addCommands( [ // DBAL Commands diff --git a/src/Tools/SchemaTool.php b/src/Tools/SchemaTool.php index 42b52df8c71..0b855ca433d 100644 --- a/src/Tools/SchemaTool.php +++ b/src/Tools/SchemaTool.php @@ -911,10 +911,6 @@ private function createSchemaForComparison(Schema $toSchema): Schema $config = $connection->getConfiguration(); $previousFilter = $config->getSchemaAssetsFilter(); - if ($previousFilter === null) { - return $this->schemaManager->introspectSchema(); - } - // whitelist assets we already know about in $toSchema, use the existing filter otherwise $config->setSchemaAssetsFilter(static function ($asset) use ($previousFilter, $toSchema): bool { $assetName = $asset instanceof AbstractAsset ? $asset->getName() : $asset; diff --git a/src/UnitOfWork.php b/src/UnitOfWork.php index e1336140640..5dfa3871d3f 100644 --- a/src/UnitOfWork.php +++ b/src/UnitOfWork.php @@ -424,17 +424,10 @@ public function commit(): void $this->executeDeletions(); } - $commitFailed = false; try { - if ($conn->commit() === false) { - $commitFailed = true; - } + $conn->commit(); } catch (DBAL\Exception $e) { - $commitFailed = true; - } - - if ($commitFailed) { - throw new OptimisticLockException('Commit failed', null, $e ?? null); + throw new OptimisticLockException('Commit failed', null, $e); } } catch (Throwable $e) { $this->em->close(); @@ -1955,12 +1948,10 @@ private function doDetach( * Refreshes the state of the given entity from the database, overwriting * any local, unpersisted changes. * - * @psalm-param LockMode::*|null $lockMode - * * @throws InvalidArgumentException If the entity is not MANAGED. * @throws TransactionRequiredException */ - public function refresh(object $entity, LockMode|int|null $lockMode = null): void + public function refresh(object $entity, LockMode|null $lockMode = null): void { $visited = []; @@ -1971,12 +1962,11 @@ public function refresh(object $entity, LockMode|int|null $lockMode = null): voi * Executes a refresh operation on an entity. * * @psalm-param array $visited The already visited entities during cascades. - * @psalm-param LockMode::*|null $lockMode * * @throws ORMInvalidArgumentException If the entity is not MANAGED. * @throws TransactionRequiredException */ - private function doRefresh(object $entity, array &$visited, LockMode|int|null $lockMode = null): void + private function doRefresh(object $entity, array &$visited, LockMode|null $lockMode = null): void { switch (true) { case $lockMode === LockMode::PESSIMISTIC_READ: @@ -2013,9 +2003,8 @@ private function doRefresh(object $entity, array &$visited, LockMode|int|null $l * Cascades a refresh operation to associated entities. * * @psalm-param array $visited - * @psalm-param LockMode::*|null $lockMode */ - private function cascadeRefresh(object $entity, array &$visited, LockMode|int|null $lockMode = null): void + private function cascadeRefresh(object $entity, array &$visited, LockMode|null $lockMode = null): void { $class = $this->em->getClassMetadata($entity::class); @@ -2204,13 +2193,11 @@ private function cascadeRemove(object $entity, array &$visited): void /** * Acquire a lock on the given entity. * - * @psalm-param LockMode::* $lockMode - * * @throws ORMInvalidArgumentException * @throws TransactionRequiredException * @throws OptimisticLockException */ - public function lock(object $entity, LockMode|int $lockMode, DateTimeInterface|int|null $lockVersion = null): void + public function lock(object $entity, LockMode $lockMode, DateTimeInterface|int|null $lockVersion = null): void { if ($this->getEntityState($entity, self::STATE_DETACHED) !== self::STATE_MANAGED) { throw ORMInvalidArgumentException::entityNotManaged($entity); diff --git a/tests/Performance/Mock/NonLoadingPersister.php b/tests/Performance/Mock/NonLoadingPersister.php index 7058092bf68..57ac4b40318 100644 --- a/tests/Performance/Mock/NonLoadingPersister.php +++ b/tests/Performance/Mock/NonLoadingPersister.php @@ -25,7 +25,7 @@ public function load( object|null $entity = null, AssociationMapping|null $assoc = null, array $hints = [], - LockMode|int|null $lockMode = null, + LockMode|null $lockMode = null, int|null $limit = null, array|null $orderBy = null, ): object|null { diff --git a/tests/Performance/Mock/NonProxyLoadingEntityManager.php b/tests/Performance/Mock/NonProxyLoadingEntityManager.php index e60e476c408..7ca18996b11 100644 --- a/tests/Performance/Mock/NonProxyLoadingEntityManager.php +++ b/tests/Performance/Mock/NonProxyLoadingEntityManager.php @@ -120,7 +120,7 @@ public function close(): void $this->realEntityManager->close(); } - public function lock(object $entity, LockMode|int $lockMode, DateTimeInterface|int|null $lockVersion = null): void + public function lock(object $entity, LockMode $lockMode, DateTimeInterface|int|null $lockVersion = null): void { $this->realEntityManager->lock($entity, $lockMode, $lockVersion); } @@ -163,7 +163,7 @@ public function hasFilters(): bool return $this->realEntityManager->hasFilters(); } - public function find(string $className, mixed $id, LockMode|int|null $lockMode = null, int|null $lockVersion = null): object|null + public function find(string $className, mixed $id, LockMode|null $lockMode = null, int|null $lockVersion = null): object|null { return $this->realEntityManager->find($className, $id, $lockMode, $lockVersion); } @@ -188,7 +188,7 @@ public function detach(object $object): void $this->realEntityManager->detach($object); } - public function refresh(object $object, LockMode|int|null $lockMode = null): void + public function refresh(object $object, LockMode|null $lockMode = null): void { $this->realEntityManager->refresh($object, $lockMode); } diff --git a/tests/Tests/DbalExtensions/Connection.php b/tests/Tests/DbalExtensions/Connection.php index 7d9ec33e3f8..b04d9203da7 100644 --- a/tests/Tests/DbalExtensions/Connection.php +++ b/tests/Tests/DbalExtensions/Connection.php @@ -4,7 +4,6 @@ namespace Doctrine\Tests\DbalExtensions; -use Doctrine\Common\EventManager; use Doctrine\DBAL\Configuration; use Doctrine\DBAL\Connection as BaseConnection; use Doctrine\DBAL\Driver; @@ -14,12 +13,12 @@ class Connection extends BaseConnection { public QueryLog $queryLog; - public function __construct(array $params, Driver $driver, Configuration|null $config = null, EventManager|null $eventManager = null) + public function __construct(array $params, Driver $driver, Configuration|null $config = null) { $this->queryLog = new QueryLog(); $logging = new LoggingMiddleware(new SqlLogger($this->queryLog)); $driver = $logging->wrap($driver); - parent::__construct($params, $driver, $config, $eventManager); + parent::__construct($params, $driver, $config); } } diff --git a/tests/Tests/DbalTypes/CustomIdObjectType.php b/tests/Tests/DbalTypes/CustomIdObjectType.php index 5cc893524ef..7a838e60cfd 100644 --- a/tests/Tests/DbalTypes/CustomIdObjectType.php +++ b/tests/Tests/DbalTypes/CustomIdObjectType.php @@ -34,9 +34,4 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform): st { return $platform->getStringTypeDeclarationSQL($column); } - - public function getName(): string - { - return self::NAME; - } } diff --git a/tests/Tests/DbalTypes/CustomIntType.php b/tests/Tests/DbalTypes/CustomIntType.php index 4ed60311e58..0175368217d 100644 --- a/tests/Tests/DbalTypes/CustomIntType.php +++ b/tests/Tests/DbalTypes/CustomIntType.php @@ -8,10 +8,4 @@ class CustomIntType extends IntegerType { - public const NAME = 'custom_int_type'; - - public function getName(): string - { - return self::NAME; - } } diff --git a/tests/Tests/DbalTypes/NegativeToPositiveType.php b/tests/Tests/DbalTypes/NegativeToPositiveType.php index 8f1896e9384..137da0dbb42 100644 --- a/tests/Tests/DbalTypes/NegativeToPositiveType.php +++ b/tests/Tests/DbalTypes/NegativeToPositiveType.php @@ -11,11 +11,6 @@ class NegativeToPositiveType extends Type { public const NAME = 'negative_to_positive'; - public function getName(): string - { - return self::NAME; - } - /** * {@inheritDoc} */ diff --git a/tests/Tests/DbalTypes/Rot13Type.php b/tests/Tests/DbalTypes/Rot13Type.php index 798b85b87ad..233dee24653 100644 --- a/tests/Tests/DbalTypes/Rot13Type.php +++ b/tests/Tests/DbalTypes/Rot13Type.php @@ -49,9 +49,4 @@ public function getSQLDeclaration(array $column, AbstractPlatform $platform): st { return $platform->getStringTypeDeclarationSQL($column); } - - public function getName(): string - { - return 'rot13'; - } } diff --git a/tests/Tests/DbalTypes/UpperCaseStringType.php b/tests/Tests/DbalTypes/UpperCaseStringType.php index 24922110cd0..a0a7657a395 100644 --- a/tests/Tests/DbalTypes/UpperCaseStringType.php +++ b/tests/Tests/DbalTypes/UpperCaseStringType.php @@ -11,11 +11,6 @@ class UpperCaseStringType extends StringType { public const NAME = 'upper_case_string'; - public function getName(): string - { - return self::NAME; - } - /** * {@inheritDoc} */ diff --git a/tests/Tests/Mocks/CompatibilityType.php b/tests/Tests/Mocks/CompatibilityType.php deleted file mode 100644 index 41417068ab2..00000000000 --- a/tests/Tests/Mocks/CompatibilityType.php +++ /dev/null @@ -1,37 +0,0 @@ -doGetBindingType(); - } - - private function doGetBindingType(): int|ParameterType - { - return parent::getBindingType(); - } - } -} else { - trait CompatibilityType - { - public function getBindingType(): ParameterType - { - return $this->doGetBindingType(); - } - - private function doGetBindingType(): int|ParameterType - { - return parent::getBindingType(); - } - } -} diff --git a/tests/Tests/Mocks/ExceptionConverterMock.php b/tests/Tests/Mocks/ExceptionConverterMock.php deleted file mode 100644 index d6e91402f4f..00000000000 --- a/tests/Tests/Mocks/ExceptionConverterMock.php +++ /dev/null @@ -1,18 +0,0 @@ -with( self::identicalTo(['name' => 'Foo']), self::identicalTo($associationMapping), - self::identicalTo(1), + self::identicalTo(LockMode::OPTIMISTIC), self::identicalTo(2), self::identicalTo(3), self::identicalTo([4]), @@ -107,7 +108,7 @@ public function testInvokeGetSelectSQL(): void self::assertSame('SELECT * FROM foo WERE name = ?', $persister->getSelectSQL( ['name' => 'Foo'], $associationMapping, - 1, + LockMode::OPTIMISTIC, 2, 3, [4], @@ -233,13 +234,21 @@ public function testInvokeLoad(): void self::identicalTo($entity), self::identicalTo($associationMapping), self::identicalTo([1]), - self::identicalTo(2), + self::identicalTo(LockMode::PESSIMISTIC_READ), self::identicalTo(3), self::identicalTo([4]), ) ->willReturn($entity); - self::assertSame($entity, $persister->load(['id' => 1], $entity, $associationMapping, [1], 2, 3, [4])); + self::assertSame($entity, $persister->load( + ['id' => 1], + $entity, + $associationMapping, + [1], + LockMode::PESSIMISTIC_READ, + 3, + [4], + )); } public function testInvokeLoadAll(): void @@ -402,9 +411,9 @@ public function testInvokeLock(): void $this->entityPersister->expects(self::once()) ->method('lock') - ->with(self::identicalTo($identifier), self::identicalTo(1)); + ->with(self::identicalTo($identifier), self::identicalTo(LockMode::OPTIMISTIC)); - $persister->lock($identifier, 1); + $persister->lock($identifier, LockMode::OPTIMISTIC); } public function testInvokeExists(): void diff --git a/tests/Tests/ORM/Functional/SchemaTool/MySqlSchemaToolTest.php b/tests/Tests/ORM/Functional/SchemaTool/MySqlSchemaToolTest.php index cbfc491d654..f2a3e89cffd 100644 --- a/tests/Tests/ORM/Functional/SchemaTool/MySqlSchemaToolTest.php +++ b/tests/Tests/ORM/Functional/SchemaTool/MySqlSchemaToolTest.php @@ -5,7 +5,6 @@ namespace Doctrine\Tests\ORM\Functional\SchemaTool; use Doctrine\DBAL\Platforms\MySQLPlatform; -use Doctrine\DBAL\Schema\Visitor\Visitor; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\Entity; use Doctrine\ORM\Mapping\GeneratedValue; @@ -21,9 +20,6 @@ use Doctrine\Tests\Models\Generic\BooleanModel; use Doctrine\Tests\Models\Generic\DecimalModel; use Doctrine\Tests\OrmFunctionalTestCase; -use PHPUnit\Framework\Attributes\Group; - -use function class_exists; class MySqlSchemaToolTest extends OrmFunctionalTestCase { @@ -51,21 +47,11 @@ public function testGetCreateSchemaSql(): void $sql = $tool->getCreateSchemaSql($classes); self::assertEquals('CREATE TABLE cms_groups (id INT AUTO_INCREMENT NOT NULL, name VARCHAR(50) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB', $sql[0]); - self::assertThat($sql[1], self::logicalOr( - // DBAL 3 - self::equalTo('CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, email_id INT DEFAULT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'), - // DBAL 4 (see https://github.com/doctrine/dbal/pull/4777) - self::equalTo('CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, email_id INT DEFAULT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'), - )); + self::assertEquals('CREATE TABLE cms_users (id INT AUTO_INCREMENT NOT NULL, status VARCHAR(50) DEFAULT NULL, username VARCHAR(255) NOT NULL, name VARCHAR(255) NOT NULL, email_id INT DEFAULT NULL, UNIQUE INDEX UNIQ_3AF03EC5F85E0677 (username), UNIQUE INDEX UNIQ_3AF03EC5A832C1C9 (email_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB', $sql[1]); self::assertEquals('CREATE TABLE cms_users_groups (user_id INT NOT NULL, group_id INT NOT NULL, INDEX IDX_7EA9409AA76ED395 (user_id), INDEX IDX_7EA9409AFE54D947 (group_id), PRIMARY KEY(user_id, group_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB', $sql[2]); self::assertEquals('CREATE TABLE cms_users_tags (user_id INT NOT NULL, tag_id INT NOT NULL, INDEX IDX_93F5A1ADA76ED395 (user_id), INDEX IDX_93F5A1ADBAD26311 (tag_id), PRIMARY KEY(user_id, tag_id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB', $sql[3]); self::assertEquals('CREATE TABLE cms_tags (id INT AUTO_INCREMENT NOT NULL, tag_name VARCHAR(50) DEFAULT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB', $sql[4]); - self::assertThat($sql[5], self::logicalOr( - // DBAL 3 - self::equalTo('CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, user_id INT DEFAULT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'), - // DBAL 4 (see https://github.com/doctrine/dbal/pull/4777) - self::equalTo('CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB'), - )); + self::assertEquals('CREATE TABLE cms_addresses (id INT AUTO_INCREMENT NOT NULL, country VARCHAR(50) NOT NULL, zip VARCHAR(50) NOT NULL, city VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, UNIQUE INDEX UNIQ_ACAC157BA76ED395 (user_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB', $sql[5]); self::assertEquals('CREATE TABLE cms_emails (id INT AUTO_INCREMENT NOT NULL, email VARCHAR(250) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB', $sql[6]); self::assertEquals('CREATE TABLE cms_phonenumbers (phonenumber VARCHAR(50) NOT NULL, user_id INT DEFAULT NULL, INDEX IDX_F21F790FA76ED395 (user_id), PRIMARY KEY(phonenumber)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB', $sql[7]); self::assertEquals('ALTER TABLE cms_users ADD CONSTRAINT FK_3AF03EC5A832C1C9 FOREIGN KEY (email_id) REFERENCES cms_emails (id)', $sql[8]); @@ -100,21 +86,6 @@ public function testGetCreateSchemaSql3(): void self::assertCount(1, $sql); self::assertEquals('CREATE TABLE boolean_model (id INT AUTO_INCREMENT NOT NULL, booleanField TINYINT(1) NOT NULL, PRIMARY KEY(id)) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB', $sql[0]); } - - #[Group('DBAL-204')] - public function testGetCreateSchemaSql4(): void - { - if (! class_exists(Visitor::class)) { - self::markTestSkipped('Test valid for doctrine/dbal:3.x only.'); - } - - $classes = [$this->_em->getClassMetadata(MysqlSchemaNamespacedEntity::class)]; - - $tool = new SchemaTool($this->_em); - $sql = $tool->getCreateSchemaSql($classes); - - self::assertCount(0, $sql); - } } #[Table('namespace.entity')] diff --git a/tests/Tests/ORM/Functional/Ticket/DDC832Test.php b/tests/Tests/ORM/Functional/Ticket/DDC832Test.php index ca7f948518e..5cf9fb9d9c4 100644 --- a/tests/Tests/ORM/Functional/Ticket/DDC832Test.php +++ b/tests/Tests/ORM/Functional/Ticket/DDC832Test.php @@ -5,7 +5,6 @@ namespace Doctrine\Tests\ORM\Functional\Ticket; use Doctrine\DBAL\Platforms\OraclePlatform; -use Doctrine\DBAL\Platforms\PostgreSQLPlatform; use Doctrine\ORM\Mapping\Column; use Doctrine\ORM\Mapping\DiscriminatorColumn; use Doctrine\ORM\Mapping\DiscriminatorMap; @@ -18,8 +17,6 @@ use Doctrine\Tests\OrmFunctionalTestCase; use PHPUnit\Framework\Attributes\Group; -use function method_exists; - class DDC832Test extends OrmFunctionalTestCase { protected function setUp(): void @@ -45,12 +42,6 @@ public function tearDown(): void $sm->dropTable($platform->quoteIdentifier('TREE_INDEX')); $sm->dropTable($platform->quoteIdentifier('INDEX')); $sm->dropTable($platform->quoteIdentifier('LIKE')); - - // DBAL 3 - if ($platform instanceof PostgreSQLPlatform && method_exists($platform, 'getIdentitySequenceName')) { - $sm->dropSequence($platform->quoteIdentifier('INDEX_id_seq')); - $sm->dropSequence($platform->quoteIdentifier('LIKE_id_seq')); - } } #[Group('DDC-832')] diff --git a/tests/Tests/ORM/Functional/Ticket/GH10462Test.php b/tests/Tests/ORM/Functional/Ticket/GH10462Test.php deleted file mode 100644 index 09820b12c2f..00000000000 --- a/tests/Tests/ORM/Functional/Ticket/GH10462Test.php +++ /dev/null @@ -1,58 +0,0 @@ -_em->getConnection()->getDatabasePlatform() instanceof MySQLPlatform) { - self::markTestSkipped('This test is useful for all databases, but designed only for mysql.'); - } - - if (method_exists(AbstractPlatform::class, 'getGuidExpression')) { - self::markTestSkipped('Test valid for doctrine/dbal:3.x only.'); - } - - $this->createSchemaForModels(GH10462Person::class, GH10462Employee::class); - $schemaManager = $this->createSchemaManager(); - $personOptions = $schemaManager->introspectTable('gh10462_person')->getColumn('discr')->toArray(); - self::assertSame('ascii', $personOptions['charset']); - self::assertSame('ascii_general_ci', $personOptions['collation']); - } -} - -#[Entity] -#[Table(name: 'gh10462_person')] -#[InheritanceType(value: 'SINGLE_TABLE')] -#[DiscriminatorColumn(name: 'discr', type: 'string', options: ['charset' => 'ascii', 'collation' => 'ascii_general_ci'])] -#[DiscriminatorMap(['person' => GH10462Person::class, 'employee' => GH10462Employee::class])] -class GH10462Person -{ - /** @var int */ - #[Id] - #[Column(type: 'integer')] - #[GeneratedValue] - public $id; -} - -#[Entity] -class GH10462Employee extends GH10462Person -{ -} diff --git a/tests/Tests/ORM/Functional/Ticket/GH9335Test.php b/tests/Tests/ORM/Functional/Ticket/GH9335Test.php index 44b082d4290..fcfac0d6b56 100644 --- a/tests/Tests/ORM/Functional/Ticket/GH9335Test.php +++ b/tests/Tests/ORM/Functional/Ticket/GH9335Test.php @@ -13,7 +13,6 @@ use Doctrine\ORM\Mapping\Id; use Doctrine\ORM\Mapping\JoinColumn; use Doctrine\ORM\Mapping\OneToOne; -use Doctrine\Tests\Mocks\CompatibilityType; use Doctrine\Tests\OrmFunctionalTestCase; use PHPUnit\Framework\Attributes\Group; @@ -54,8 +53,6 @@ public function testFlattenIdentifierWithObjectId(): void class GH9335IntObjectType extends Type { - use CompatibilityType; - public function getSQLDeclaration(array $column, AbstractPlatform $platform): string { return $platform->getIntegerTypeDeclarationSQL($column); @@ -76,7 +73,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform): GH9335Int return new GH9335IntObject((int) $value); } - private function doGetBindingType(): ParameterType|int + public function getBindingType(): ParameterType { return ParameterType::INTEGER; } diff --git a/tests/Tests/ORM/Functional/TypeTest.php b/tests/Tests/ORM/Functional/TypeTest.php index 9743ebcfb17..4118a49e4f2 100644 --- a/tests/Tests/ORM/Functional/TypeTest.php +++ b/tests/Tests/ORM/Functional/TypeTest.php @@ -6,18 +6,12 @@ use DateTime; use DateTimeZone; -use Doctrine\DBAL\Types\ArrayType; -use Doctrine\DBAL\Types\ObjectType; use Doctrine\DBAL\Types\Types; use Doctrine\Tests\Models\Generic\BooleanModel; use Doctrine\Tests\Models\Generic\DateTimeModel; use Doctrine\Tests\Models\Generic\DecimalModel; -use Doctrine\Tests\Models\Generic\SerializationModel; use Doctrine\Tests\OrmFunctionalTestCase; use PHPUnit\Framework\Attributes\Group; -use stdClass; - -use function class_exists; class TypeTest extends OrmFunctionalTestCase { @@ -71,49 +65,6 @@ public function testBoolean(): void self::assertFalse($bool->booleanField); } - public function testArray(): void - { - if (! class_exists(ArrayType::class)) { - self::markTestSkipped('Test valid for doctrine/dbal:3.x only.'); - } - - $serialize = new SerializationModel(); - $serialize->array['foo'] = 'bar'; - $serialize->array['bar'] = 'baz'; - - $this->createSchemaForModels(SerializationModel::class); - static::$sharedConn->executeStatement('DELETE FROM serialize_model'); - $this->_em->persist($serialize); - $this->_em->flush(); - $this->_em->clear(); - - $dql = 'SELECT s FROM ' . SerializationModel::class . ' s'; - $serialize = $this->_em->createQuery($dql)->getSingleResult(); - - self::assertSame(['foo' => 'bar', 'bar' => 'baz'], $serialize->array); - } - - public function testObject(): void - { - if (! class_exists(ObjectType::class)) { - self::markTestSkipped('Test valid for doctrine/dbal:3.x only.'); - } - - $serialize = new SerializationModel(); - $serialize->object = new stdClass(); - - $this->createSchemaForModels(SerializationModel::class); - static::$sharedConn->executeStatement('DELETE FROM serialize_model'); - $this->_em->persist($serialize); - $this->_em->flush(); - $this->_em->clear(); - - $dql = 'SELECT s FROM ' . SerializationModel::class . ' s'; - $serialize = $this->_em->createQuery($dql)->getSingleResult(); - - self::assertInstanceOf(stdClass::class, $serialize->object); - } - public function testDate(): void { $dateTime = new DateTimeModel(); diff --git a/tests/Tests/ORM/Query/ParameterTypeInfererTest.php b/tests/Tests/ORM/Query/ParameterTypeInfererTest.php index 3a983af42a9..348122c7edc 100644 --- a/tests/Tests/ORM/Query/ParameterTypeInfererTest.php +++ b/tests/Tests/ORM/Query/ParameterTypeInfererTest.php @@ -19,7 +19,7 @@ class ParameterTypeInfererTest extends OrmTestCase { - /** @psalm-return Generator */ + /** @psalm-return Generator */ public static function providerParameterTypeInferer(): Generator { yield 'integer' => [1, Types::INTEGER]; @@ -40,7 +40,7 @@ public static function providerParameterTypeInferer(): Generator } #[DataProvider('providerParameterTypeInferer')] - public function testParameterTypeInferer(mixed $value, ParameterType|ArrayParameterType|int|string $expected): void + public function testParameterTypeInferer(mixed $value, ParameterType|ArrayParameterType|string $expected): void { self::assertEquals($expected, ParameterTypeInferer::inferType($value)); } diff --git a/tests/Tests/ORM/Query/SelectSqlGenerationTest.php b/tests/Tests/ORM/Query/SelectSqlGenerationTest.php index 681562c1dd8..b4d74bc543f 100644 --- a/tests/Tests/ORM/Query/SelectSqlGenerationTest.php +++ b/tests/Tests/ORM/Query/SelectSqlGenerationTest.php @@ -32,11 +32,6 @@ use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; -use function class_exists; - -// DBAL 3 compatibility -class_exists('Doctrine\\DBAL\\Platforms\\SqlitePlatform'); - class SelectSqlGenerationTest extends OrmTestCase { private EntityManagerInterface $entityManager; @@ -806,13 +801,9 @@ public function testLimitAndOffsetFromQueryClass(): void ->setMaxResults(10) ->setFirstResult(0); - // DBAL 2.8+ doesn't add OFFSET part when offset is 0 - self::assertThat( + self::assertSame( + 'SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c0_.email_id AS email_id_4 FROM cms_users c0_ LIMIT 10', $q->getSql(), - self::logicalOr( - self::identicalTo('SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c0_.email_id AS email_id_4 FROM cms_users c0_ LIMIT 10'), - self::identicalTo('SELECT c0_.id AS id_0, c0_.status AS status_1, c0_.username AS username_2, c0_.name AS name_3, c0_.email_id AS email_id_4 FROM cms_users c0_ LIMIT 10 OFFSET 0'), - ), ); } diff --git a/tests/Tests/ORM/Tools/Console/ConsoleRunnerTest.php b/tests/Tests/ORM/Tools/Console/ConsoleRunnerTest.php index 3d3d89f4b4b..5a6a76d75bd 100644 --- a/tests/Tests/ORM/Tools/Console/ConsoleRunnerTest.php +++ b/tests/Tests/ORM/Tools/Console/ConsoleRunnerTest.php @@ -5,7 +5,6 @@ namespace Doctrine\Tests\ORM\Tools\Console; use Composer\InstalledVersions; -use DBALConsole\Command\ReservedWordsCommand; use Doctrine\ORM\Tools\Console\ConsoleRunner; use Doctrine\ORM\Tools\Console\EntityManagerProvider; use PHPUnit\Framework\Attributes\CoversClass; @@ -13,8 +12,6 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Command\Command; -use function class_exists; - #[CoversClass(ConsoleRunner::class)] #[Group('DDC-3186')] final class ConsoleRunnerTest extends TestCase @@ -24,9 +21,6 @@ public function testCreateApplicationShouldReturnAnApplicationWithTheCorrectComm $app = ConsoleRunner::createApplication($this->createStub(EntityManagerProvider::class)); self::assertSame(InstalledVersions::getVersion('doctrine/orm'), $app->getVersion()); - if (class_exists(ReservedWordsCommand::class)) { - self::assertTrue($app->has('dbal:reserved-words')); - } self::assertTrue($app->has('dbal:run-sql')); self::assertTrue($app->has('orm:clear-cache:region:collection')); diff --git a/tests/Tests/ORM/UnitOfWorkTest.php b/tests/Tests/ORM/UnitOfWorkTest.php index 550b1cfe1c8..35960f1d770 100644 --- a/tests/Tests/ORM/UnitOfWorkTest.php +++ b/tests/Tests/ORM/UnitOfWorkTest.php @@ -5,7 +5,6 @@ namespace Doctrine\Tests\ORM; use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\Common\EventManager; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Driver; use Doctrine\DBAL\Driver\Statement; @@ -34,7 +33,6 @@ use Doctrine\Tests\OrmTestCase; use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\Attributes\Group; -use PHPUnit\Framework\MockObject\MockObject; use stdClass; use function random_int; @@ -60,8 +58,6 @@ class UnitOfWorkTest extends OrmTestCase */ private EntityManagerMock $_emMock; - private EventManager&MockObject $eventManager; - protected function setUp(): void { parent::setUp(); @@ -84,9 +80,8 @@ protected function setUp(): void $driver->method('connect') ->willReturn($driverConnection); - $this->eventManager = $this->getMockBuilder(EventManager::class)->getMock(); - $this->connection = new Connection([], $driver, null, $this->eventManager); - $this->_emMock = new EntityManagerMock($this->connection); + $this->connection = new Connection([], $driver, null); + $this->_emMock = new EntityManagerMock($this->connection); // SUT $this->_unitOfWork = new UnitOfWorkMock($this->_emMock); $this->_emMock->setUnitOfWork($this->_unitOfWork);