Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions src/Internal/Hydration/AbstractHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
use BackedEnum;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\TypeProvider;
use Doctrine\DBAL\Types\TypeRegistry;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Events;
use Doctrine\ORM\Internal\TypeProviderLocator;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Query\ResultSetMapping;
use Doctrine\ORM\Tools\Pagination\LimitSubqueryWalker;
Expand Down Expand Up @@ -54,6 +56,8 @@
*/
protected UnitOfWork $uow;

private readonly TypeProvider|TypeRegistry $typeProvider;

Check failure on line 59 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Property Doctrine\ORM\Internal\Hydration\AbstractHydrator::$typeProvider has unknown class Doctrine\DBAL\Types\TypeProvider as its type.

Check failure on line 59 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Property Doctrine\ORM\Internal\Hydration\AbstractHydrator::$typeProvider has unknown class Doctrine\DBAL\Types\TypeProvider as its type.

/**
* Local ClassMetadata cache to avoid going to the EntityManager all the time.
*
Expand Down Expand Up @@ -85,8 +89,9 @@
*/
public function __construct(protected EntityManagerInterface $em)
{
$this->platform = $em->getConnection()->getDatabasePlatform();
$this->uow = $em->getUnitOfWork();
$this->platform = $em->getConnection()->getDatabasePlatform();
$this->uow = $em->getUnitOfWork();
$this->typeProvider = TypeProviderLocator::fromConnection($em->getConnection());
}

/**
Expand Down Expand Up @@ -458,7 +463,7 @@
$columnInfo = [
'isIdentifier' => in_array($fieldName, $classMetadata->identifier, true),
'fieldName' => $fieldName,
'type' => Type::getType($fieldMapping->type),
'type' => $this->typeProvider->get($fieldMapping->type),

Check failure on line 466 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.

Check failure on line 466 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.
'dqlAlias' => $ownerMap,
'enumType' => $this->rsm->enumMappings[$key] ?? null,
];
Expand Down Expand Up @@ -486,7 +491,7 @@
'isScalar' => true,
'isNewObjectParameter' => true,
'fieldName' => $this->rsm->scalarMappings[$key],
'type' => Type::getType($this->rsm->typeMappings[$key]),
'type' => $this->typeProvider->get($this->rsm->typeMappings[$key]),

Check failure on line 494 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.

Check failure on line 494 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.
'argIndex' => $mapping['argIndex'],
'objIndex' => $mapping['objIndex'],
'enumType' => $this->rsm->enumMappings[$key] ?? null,
Expand All @@ -495,7 +500,7 @@
case isset($this->rsm->scalarMappings[$key], $this->hints[LimitSubqueryWalker::FORCE_DBAL_TYPE_CONVERSION]):
return $this->cache[$key] = [
'fieldName' => $this->rsm->scalarMappings[$key],
'type' => Type::getType($this->rsm->typeMappings[$key]),
'type' => $this->typeProvider->get($this->rsm->typeMappings[$key]),

Check failure on line 503 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.

Check failure on line 503 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.
'dqlAlias' => '',
'enumType' => $this->rsm->enumMappings[$key] ?? null,
];
Expand All @@ -504,7 +509,7 @@
return $this->cache[$key] = [
'isScalar' => true,
'fieldName' => $this->rsm->scalarMappings[$key],
'type' => Type::getType($this->rsm->typeMappings[$key]),
'type' => $this->typeProvider->get($this->rsm->typeMappings[$key]),

Check failure on line 512 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.

Check failure on line 512 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.
'enumType' => $this->rsm->enumMappings[$key] ?? null,
];

Expand All @@ -513,7 +518,7 @@
$fieldName = $this->rsm->metaMappings[$key];
$dqlAlias = $this->rsm->columnOwnerMap[$key];
$type = isset($this->rsm->typeMappings[$key])
? Type::getType($this->rsm->typeMappings[$key])
? $this->typeProvider->get($this->rsm->typeMappings[$key])

Check failure on line 521 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.

Check failure on line 521 in src/Internal/Hydration/AbstractHydrator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.
: null;

// Cache metadata fetch
Expand Down
33 changes: 33 additions & 0 deletions src/Internal/TypeProviderLocator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

declare(strict_types=1);

namespace Doctrine\ORM\Internal;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\TypeProvider;
use Doctrine\DBAL\Types\TypeRegistry;

use function method_exists;

/**
* Resolves the {@see TypeProvider} owned by a DBAL connection.
*
* @internal
*/
final class TypeProviderLocator
{
public static function fromConnection(Connection $connection): TypeProvider|TypeRegistry

Check failure on line 21 in src/Internal/TypeProviderLocator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Method Doctrine\ORM\Internal\TypeProviderLocator::fromConnection() has invalid return type Doctrine\DBAL\Types\TypeProvider.

Check failure on line 21 in src/Internal/TypeProviderLocator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Method Doctrine\ORM\Internal\TypeProviderLocator::fromConnection() has invalid return type Doctrine\DBAL\Types\TypeProvider.
{
$configuration = $connection->getConfiguration();

// The method_exists() check is for DBAL < 4.5 compatibility, where Configuration::getTypeProvider() does not exist yet.
// @phpstan-ignore function.alreadyNarrowedType (DBAL < 4.5 compatibility)
if (method_exists($configuration, 'getTypeProvider')) {

Check failure on line 27 in src/Internal/TypeProviderLocator.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

No error with identifier function.alreadyNarrowedType is reported on line 27.
return $configuration->getTypeProvider();
}

return Type::getTypeRegistry();
}
}
4 changes: 3 additions & 1 deletion src/Mapping/Driver/DatabaseDriver.php
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,9 @@
$fieldMapping = [
'fieldName' => $this->getFieldNameForColumn($tableName, self::getAssetName($column), false),
'columnName' => self::getAssetName($column),
'type' => Type::getTypeRegistry()->lookupName($column->getType()),
'type' => method_exists($column, 'getTypeName')

Check failure on line 425 in src/Mapping/Driver/DatabaseDriver.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to function method_exists() with Doctrine\DBAL\Schema\Column and 'getTypeName' will always evaluate to false.
? $column->getTypeName()
: Type::getTypeRegistry()->lookupName($column->getType()),
'nullable' => ! $column->getNotnull(),
'options' => [
'comment' => $column->getComment(),
Expand Down
5 changes: 3 additions & 2 deletions src/Persisters/Collection/OneToManyPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
use BadMethodCallException;
use Doctrine\Common\Collections\Criteria;
use Doctrine\DBAL\Exception as DBALException;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityNotFoundException;
use Doctrine\ORM\Internal\TypeProviderLocator;
use Doctrine\ORM\Mapping\MappingException;
use Doctrine\ORM\Mapping\OneToManyAssociationMapping;
use Doctrine\ORM\PersistentCollection;
Expand Down Expand Up @@ -219,12 +219,13 @@
$idColumnNames = $rootClass->getIdentifierColumnNames();
$idColumnList = implode(', ', $idColumnNames);
$columnDefinitions = [];
$typeProvider = TypeProviderLocator::fromConnection($this->em->getConnection());

foreach ($idColumnNames as $idColumnName) {
$columnDefinitions[$idColumnName] = [
'name' => $idColumnName,
'notnull' => true,
'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $this->em)),
'type' => $typeProvider->get(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $this->em)),

Check failure on line 228 in src/Persisters/Collection/OneToManyPersister.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (default, phpstan.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.

Check failure on line 228 in src/Persisters/Collection/OneToManyPersister.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.
];
}

Expand Down
3 changes: 1 addition & 2 deletions src/Persisters/Entity/AbstractEntityInheritancePersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@

namespace Doctrine\ORM\Persisters\Entity;

use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Mapping\ClassMetadata;

use function sprintf;
Expand Down Expand Up @@ -57,7 +56,7 @@ protected function getSelectColumnSQL(string $field, ClassMetadata $class, strin

$this->currentPersisterContext->rsm->addFieldResult($alias, $columnAlias, $field, $class->name);

$type = Type::getType($fieldMapping->type);
$type = $this->getType($fieldMapping->type);
$sql = $type->convertToPHPValueSQL($sql, $this->platform);

return $sql . ' AS ' . $columnAlias;
Expand Down
21 changes: 16 additions & 5 deletions src/Persisters/Entity/BasicEntityPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,12 @@
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\TypeProvider;
use Doctrine\DBAL\Types\TypeRegistry;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Cache\Persister\CompatOrderings;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Internal\TypeProviderLocator;
use Doctrine\ORM\Mapping\AssociationMapping;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\JoinColumnMapping;
Expand Down Expand Up @@ -120,6 +123,8 @@
*/
protected Connection $conn;

private readonly TypeProvider|TypeRegistry $typeProvider;

Check failure on line 126 in src/Persisters/Entity/BasicEntityPersister.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Property Doctrine\ORM\Persisters\Entity\BasicEntityPersister::$typeProvider has unknown class Doctrine\DBAL\Types\TypeProvider as its type.

/**
* The database platform.
*/
Expand Down Expand Up @@ -181,6 +186,7 @@
) {
$this->conn = $em->getConnection();
$this->platform = $this->conn->getDatabasePlatform();
$this->typeProvider = TypeProviderLocator::fromConnection($this->conn);
$this->quoteStrategy = $em->getConfiguration()->getQuoteStrategy();
$this->identifierFlattener = new IdentifierFlattener($em->getUnitOfWork(), $em->getMetadataFactory());
$this->noLimitsContext = $this->currentPersisterContext = new CachedPersisterContext(
Expand All @@ -205,6 +211,11 @@
$this->filterHash = $this->em->getFilters()->getHash();
}

final protected function getType(string $name): Type
{
return $this->typeProvider->get($name);

Check failure on line 216 in src/Persisters/Entity/BasicEntityPersister.php

View workflow job for this annotation

GitHub Actions / Static Analysis with PHPStan (3.8.2, phpstan-dbal3.neon)

Call to method get() on an unknown class Doctrine\DBAL\Types\TypeProvider.
}

public function getClassMetadata(): ClassMetadata
{
return $this->class;
Expand Down Expand Up @@ -292,7 +303,7 @@
$values = $this->fetchVersionAndNotUpsertableValues($this->class, $id);

foreach ($values as $field => $value) {
$value = Type::getType($this->class->fieldMappings[$field]->type)->convertToPHPValue($value, $this->platform);
$value = $this->getType($this->class->fieldMappings[$field]->type)->convertToPHPValue($value, $this->platform);

$this->class->setFieldValue($entity, $field, $value);
}
Expand Down Expand Up @@ -418,7 +429,7 @@
$column = $this->quoteStrategy->getColumnName($fieldName, $this->class, $this->platform);

if (isset($this->class->fieldMappings[$fieldName])) {
$type = Type::getType($this->columnTypes[$columnName]);
$type = $this->getType($this->columnTypes[$columnName]);
$placeholder = $type->convertToDatabaseValueSQL('?', $this->platform);
}

Expand Down Expand Up @@ -1457,7 +1468,7 @@
&& isset($this->columnTypes[$this->class->fieldNames[$column]])
&& isset($this->class->fieldMappings[$this->class->fieldNames[$column]])
) {
$type = Type::getType($this->columnTypes[$this->class->fieldNames[$column]]);
$type = $this->getType($this->columnTypes[$this->class->fieldNames[$column]]);
$placeholder = $type->convertToDatabaseValueSQL('?', $this->platform);
}

Expand Down Expand Up @@ -1543,7 +1554,7 @@
$this->currentPersisterContext->rsm->addEnumResult($columnAlias, $fieldMapping->enumType);
}

$type = Type::getType($fieldMapping->type);
$type = $this->getType($fieldMapping->type);
$sql = $type->convertToPHPValueSQL($sql, $this->platform);

return $sql . ' AS ' . $columnAlias;
Expand Down Expand Up @@ -1650,7 +1661,7 @@
$placeholder = '?';

if (isset($this->class->fieldMappings[$field])) {
$type = Type::getType($this->class->fieldMappings[$field]->type);
$type = $this->getType($this->class->fieldMappings[$field]->type);
$placeholder = $type->convertToDatabaseValueSQL($placeholder, $this->platform);
}

Expand Down
3 changes: 1 addition & 2 deletions src/Persisters/Entity/JoinedSubclassPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use Doctrine\Common\Collections\Criteria;
use Doctrine\DBAL\LockMode;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use Doctrine\ORM\Internal\SQLResultCasing;
use Doctrine\ORM\Mapping\AssociationMapping;
Expand Down Expand Up @@ -511,7 +510,7 @@ protected function assignDefaultVersionAndUpsertableValues(object $entity, array
$values = $this->fetchVersionAndNotUpsertableValues($this->getVersionedClassMetadata(), $id);

foreach ($values as $field => $value) {
$value = Type::getType($this->class->fieldMappings[$field]->type)->convertToPHPValue($value, $this->platform);
$value = $this->getType($this->class->fieldMappings[$field]->type)->convertToPHPValue($value, $this->platform);

$this->class->setFieldValue($entity, $field, $value);
}
Expand Down
5 changes: 3 additions & 2 deletions src/Query/Exec/MultiTableDeleteExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Internal\TypeProviderLocator;
use Doctrine\ORM\Query\AST;
use Doctrine\ORM\Query\AST\DeleteStatement;
use Doctrine\ORM\Query\SqlWalker;
Expand Down Expand Up @@ -86,11 +86,12 @@ public function __construct(AST\Node $AST, SqlWalker $sqlWalker)

// 4. Store DDL for temporary identifier table.
$columnDefinitions = [];
$typeProvider = TypeProviderLocator::fromConnection($em->getConnection());
foreach ($idColumnNames as $idColumnName) {
$columnDefinitions[$idColumnName] = [
'name' => $idColumnName,
'notnull' => true,
'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)),
'type' => $typeProvider->get(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)),
];
}

Expand Down
5 changes: 3 additions & 2 deletions src/Query/Exec/MultiTableUpdateExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Internal\TypeProviderLocator;
use Doctrine\ORM\Query\AST;
use Doctrine\ORM\Query\AST\UpdateStatement;
use Doctrine\ORM\Query\ParameterTypeInferer;
Expand Down Expand Up @@ -125,12 +125,13 @@ public function __construct(AST\Node $AST, SqlWalker $sqlWalker)

// 4. Store DDL for temporary identifier table.
$columnDefinitions = [];
$typeProvider = TypeProviderLocator::fromConnection($em->getConnection());

foreach ($idColumnNames as $idColumnName) {
$columnDefinitions[$idColumnName] = [
'name' => $idColumnName,
'notnull' => true,
'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)),
'type' => $typeProvider->get(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)),
];
}

Expand Down
7 changes: 4 additions & 3 deletions src/Query/ResultSetMappingBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@

namespace Doctrine\ORM\Query;

use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Internal\SQLResultCasing;
use Doctrine\ORM\Internal\TypeProviderLocator;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Utility\PersisterHelper;
use InvalidArgumentException;
Expand Down Expand Up @@ -238,7 +238,8 @@ private function getColumnAliasMap(
*/
public function generateSelectClause(array $tableAliases = []): string
{
$sql = '';
$sql = '';
$typeProvider = TypeProviderLocator::fromConnection($this->em->getConnection());

foreach ($this->columnOwnerMap as $columnName => $dqlAlias) {
$tableAlias = $tableAliases[$dqlAlias] ?? $dqlAlias;
Expand All @@ -253,7 +254,7 @@ public function generateSelectClause(array $tableAliases = []): string
$classFieldMapping = $class->fieldMappings[$fieldName];
$columnSql = $tableAlias . '.' . $classFieldMapping->columnName;

$type = Type::getType($classFieldMapping->type);
$type = $typeProvider->get($classFieldMapping->type);
$columnSql = $type->convertToPHPValueSQL($columnSql, $this->em->getConnection()->getDatabasePlatform());

$sql .= $columnSql;
Expand Down
Loading
Loading