Skip to content
Draft
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
18 changes: 18 additions & 0 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
namespace Doctrine\ORM;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\TypeRegistry;
use Doctrine\Deprecations\Deprecation;
use Doctrine\ORM\Cache\CacheConfiguration;
use Doctrine\ORM\Exception\InvalidEntityRepository;
Expand All @@ -29,6 +31,7 @@

use function class_exists;
use function is_a;
use function method_exists;
use function strtolower;

use const PHP_VERSION_ID;
Expand Down Expand Up @@ -723,4 +726,19 @@
{
return $this->attributes['fetchModeSubselectBatchSize'] ?? 100;
}

/**
* Returns the type registry for this configuration.
* Falls back to the global type registry when running against DBAL < 4.5,
* which does not have {@see \Doctrine\DBAL\Configuration::getTypeRegistry()}.
*/
public function getTypeRegistry(): TypeRegistry
{
// @phpstan-ignore function.alreadyNarrowedType (method_exists check is for DBAL v3 compatibility)
if (method_exists(parent::class, 'getTypeRegistry')) {

Check failure on line 738 in src/Configuration.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 738.
return parent::getTypeRegistry();
}

return Type::getTypeRegistry();
}
}
15 changes: 10 additions & 5 deletions src/Internal/Hydration/AbstractHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,11 @@ public function __construct(protected EntityManagerInterface $em)
$this->uow = $em->getUnitOfWork();
}

private function getType(string $name): Type
{
return $this->em->getConfiguration()->getTypeRegistry()->get($name);
}

/**
* Initiates a row-by-row hydration.
*
Expand Down Expand Up @@ -458,7 +463,7 @@ protected function hydrateColumnInfo(string $key): array|null
$columnInfo = [
'isIdentifier' => in_array($fieldName, $classMetadata->identifier, true),
'fieldName' => $fieldName,
'type' => Type::getType($fieldMapping->type),
'type' => $this->getType($fieldMapping->type),
'dqlAlias' => $ownerMap,
'enumType' => $this->rsm->enumMappings[$key] ?? null,
];
Expand Down Expand Up @@ -486,7 +491,7 @@ protected function hydrateColumnInfo(string $key): array|null
'isScalar' => true,
'isNewObjectParameter' => true,
'fieldName' => $this->rsm->scalarMappings[$key],
'type' => Type::getType($this->rsm->typeMappings[$key]),
'type' => $this->getType($this->rsm->typeMappings[$key]),
'argIndex' => $mapping['argIndex'],
'objIndex' => $mapping['objIndex'],
'enumType' => $this->rsm->enumMappings[$key] ?? null,
Expand All @@ -495,7 +500,7 @@ protected function hydrateColumnInfo(string $key): array|null
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->getType($this->rsm->typeMappings[$key]),
'dqlAlias' => '',
'enumType' => $this->rsm->enumMappings[$key] ?? null,
];
Expand All @@ -504,7 +509,7 @@ protected function hydrateColumnInfo(string $key): array|null
return $this->cache[$key] = [
'isScalar' => true,
'fieldName' => $this->rsm->scalarMappings[$key],
'type' => Type::getType($this->rsm->typeMappings[$key]),
'type' => $this->getType($this->rsm->typeMappings[$key]),
'enumType' => $this->rsm->enumMappings[$key] ?? null,
];

Expand All @@ -513,7 +518,7 @@ protected function hydrateColumnInfo(string $key): array|null
$fieldName = $this->rsm->metaMappings[$key];
$dqlAlias = $this->rsm->columnOwnerMap[$key];
$type = isset($this->rsm->typeMappings[$key])
? Type::getType($this->rsm->typeMappings[$key])
? $this->getType($this->rsm->typeMappings[$key])
: null;

// Cache metadata fetch
Expand Down
3 changes: 1 addition & 2 deletions src/Persisters/Collection/OneToManyPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
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\Mapping\MappingException;
use Doctrine\ORM\Mapping\OneToManyAssociationMapping;
Expand Down Expand Up @@ -224,7 +223,7 @@ private function deleteJoinedEntityCollection(PersistentCollection $collection):
$columnDefinitions[$idColumnName] = [
'name' => $idColumnName,
'notnull' => true,
'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $this->em)),
'type' => $this->em->getConfiguration()->getTypeRegistry()->get(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $this->em)),
];
}

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 @@ -49,7 +48,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
15 changes: 10 additions & 5 deletions src/Persisters/Entity/BasicEntityPersister.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,11 @@ final protected function updateFilterHash(): void
$this->filterHash = $this->em->getFilters()->getHash();
}

final protected function getType(string $name): Type
{
return $this->em->getConfiguration()->getTypeRegistry()->get($name);
}

public function getClassMetadata(): ClassMetadata
{
return $this->class;
Expand Down Expand Up @@ -290,7 +295,7 @@ protected function assignDefaultVersionAndUpsertableValues(object $entity, array
$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 @@ -416,7 +421,7 @@ final protected function updateTable(
$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 @@ -1453,7 +1458,7 @@ public function getInsertSQL(): string
&& 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 @@ -1539,7 +1544,7 @@ protected function getSelectColumnSQL(string $field, ClassMetadata $class, strin
$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 @@ -1646,7 +1651,7 @@ public function getSelectConditionStatementSQL(
$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
3 changes: 1 addition & 2 deletions src/Query/Exec/MultiTableDeleteExecutor.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Query\AST;
use Doctrine\ORM\Query\AST\DeleteStatement;
use Doctrine\ORM\Query\SqlWalker;
Expand Down Expand Up @@ -90,7 +89,7 @@ public function __construct(AST\Node $AST, SqlWalker $sqlWalker)
$columnDefinitions[$idColumnName] = [
'name' => $idColumnName,
'notnull' => true,
'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)),
'type' => $em->getConfiguration()->getTypeRegistry()->get(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)),
];
}

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

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Connections\PrimaryReadReplicaConnection;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Query\AST;
use Doctrine\ORM\Query\AST\UpdateStatement;
use Doctrine\ORM\Query\ParameterTypeInferer;
Expand Down Expand Up @@ -130,7 +129,7 @@ public function __construct(AST\Node $AST, SqlWalker $sqlWalker)
$columnDefinitions[$idColumnName] = [
'name' => $idColumnName,
'notnull' => true,
'type' => Type::getType(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)),
'type' => $em->getConfiguration()->getTypeRegistry()->get(PersisterHelper::getTypeOfColumn($idColumnName, $rootClass, $em)),
];
}

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

namespace Doctrine\ORM\Query;

use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Internal\SQLResultCasing;
use Doctrine\ORM\Mapping\ClassMetadata;
Expand Down Expand Up @@ -253,7 +252,7 @@ public function generateSelectClause(array $tableAliases = []): string
$classFieldMapping = $class->fieldMappings[$fieldName];
$columnSql = $tableAlias . '.' . $classFieldMapping->columnName;

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

$sql .= $columnSql;
Expand Down
24 changes: 17 additions & 7 deletions src/Query/SqlWalker.php
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,16 @@ public function getEntityManager(): EntityManagerInterface
return $this->em;
}

private function getType(string $name): Type
{
return $this->em->getConfiguration()->getTypeRegistry()->get($name);
}

private function hasType(string $name): bool
{
return $this->em->getConfiguration()->getTypeRegistry()->has($name);
}

/**
* Gets the information about a single query component.
*
Expand Down Expand Up @@ -1290,7 +1300,7 @@ public function walkSelectExpression(AST\SelectExpression $selectExpression): st
$columnAlias = $this->getSQLColumnAlias($fieldMapping->columnName);
$col = $sqlTableAlias . '.' . $columnName;

$type = Type::getType($fieldMapping->type);
$type = $this->getType($fieldMapping->type);
$col = $type->convertToPHPValueSQL($col, $this->conn->getDatabasePlatform());

$sql .= $col . ' AS ' . $columnAlias;
Expand Down Expand Up @@ -1338,7 +1348,7 @@ public function walkSelectExpression(AST\SelectExpression $selectExpression): st
break;
}

$this->rsm->addScalarResult($columnAlias, $resultAlias, Type::getTypeRegistry()->lookupName($expr->getReturnType()));
$this->rsm->addScalarResult($columnAlias, $resultAlias, $this->em->getConfiguration()->getTypeRegistry()->lookupName($expr->getReturnType()));

break;

Expand Down Expand Up @@ -1416,7 +1426,7 @@ public function walkObjectExpression(string $dqlAlias, array $partialFieldSet, s

$col = $sqlTableAlias . '.' . $quotedColumnName;

$type = Type::getType($mapping->type);
$type = $this->getType($mapping->type);
$col = $type->convertToPHPValueSQL($col, $this->platform);

$sqlParts[] = $col . ' AS ' . $columnAlias;
Expand Down Expand Up @@ -1451,7 +1461,7 @@ public function walkObjectExpression(string $dqlAlias, array $partialFieldSet, s

$col = $sqlTableAlias . '.' . $quotedColumnName;

$type = Type::getType($mapping->type);
$type = $this->getType($mapping->type);
$col = $type->convertToPHPValueSQL($col, $this->platform);

$sqlParts[] = $col . ' AS ' . $columnAlias;
Expand Down Expand Up @@ -1556,7 +1566,7 @@ public function walkNewObject(AST\NewObjectExpression $newObjectExpression, stri
$fieldType = $fieldMapping->type;
$col = trim($e->dispatch($this));

$type = Type::getType($fieldType);
$type = $this->getType($fieldType);
$col = $type->convertToPHPValueSQL($col, $this->platform);

$sqlSelectExpressions[] = $col . ' AS ' . $columnAlias;
Expand Down Expand Up @@ -2189,8 +2199,8 @@ public function walkInputParameter(AST\InputParameter $inputParam): string

if ($parameter) {
$type = $parameter->getType();
if (is_string($type) && Type::hasType($type)) {
return Type::getType($type)->convertToDatabaseValueSQL('?', $this->platform);
if (is_string($type) && $this->hasType($type)) {
return $this->getType($type)->convertToDatabaseValueSQL('?', $this->platform);
}
}

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

namespace Doctrine\ORM\Tools\Pagination;

use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Query;
use Doctrine\ORM\Query\AST\Functions\IdentityFunction;
use Doctrine\ORM\Query\AST\Node;
Expand Down Expand Up @@ -51,7 +50,7 @@ public function walkSelectStatement(SelectStatement $selectStatement): void

$query->setHint(
self::IDENTIFIER_TYPE,
Type::getType($rootClass->fieldMappings[$identifier]->type),
$query->getEntityManager()->getConfiguration()->getTypeRegistry()->get($rootClass->fieldMappings[$identifier]->type),
);

$query->setHint(self::FORCE_DBAL_TYPE_CONVERSION, true);
Expand Down
6 changes: 3 additions & 3 deletions src/Tools/SchemaValidator.php
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ public function validateClass(ClassMetadata $class): array
$cmf = $this->em->getMetadataFactory();

foreach ($class->fieldMappings as $fieldName => $mapping) {
if (! Type::hasType($mapping->type)) {
if (! $this->em->getConfiguration()->getTypeRegistry()->has($mapping->type)) {
$ce[] = "The field '" . $class->name . '#' . $fieldName . "' uses a non-existent type '" . $mapping->type . "'.";
}
}
Expand Down Expand Up @@ -332,7 +332,7 @@ function (FieldMapping $fieldMapping) use ($class): string|null {
$propertyType = $class->propertyAccessors[$fieldName]->getUnderlyingReflector()->getType();

// If the field type is not a built-in type, we cannot check it
if (! Type::hasType($fieldMapping->type)) {
if (! $this->em->getConfiguration()->getTypeRegistry()->has($fieldMapping->type)) {
return null;
}

Expand All @@ -341,7 +341,7 @@ function (FieldMapping $fieldMapping) use ($class): string|null {
return null;
}

$metadataFieldType = $this->findBuiltInType(Type::getType($fieldMapping->type));
$metadataFieldType = $this->findBuiltInType($this->em->getConfiguration()->getTypeRegistry()->get($fieldMapping->type));

//If the metadata field type is not a mapped built-in type, we cannot check it
if ($metadataFieldType === null) {
Expand Down
7 changes: 3 additions & 4 deletions src/Utility/PersisterHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
use BackedEnum;
use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\ParameterType;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Proxy\DefaultProxyClassNameResolver;
Expand Down Expand Up @@ -160,17 +159,17 @@ public static function inferParameterTypes(
}

if (is_array($value)) {
return array_map(self::getArrayBindingType(...), $types);
return array_map(static fn ($t) => self::getArrayBindingType($t, $em), $types);
}

return $types;
}

/** @phpstan-return ArrayParameterType::* */
private static function getArrayBindingType(ParameterType|int|string $type): ArrayParameterType|int
private static function getArrayBindingType(ParameterType|int|string $type, EntityManagerInterface $em): ArrayParameterType|int
{
if (! $type instanceof ParameterType) {
$type = Type::getType((string) $type)->getBindingType();
$type = $em->getConfiguration()->getTypeRegistry()->get((string) $type)->getBindingType();
}

return match ($type) {
Expand Down
Loading