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
3 changes: 2 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@
"slevomat/coding-standard": "8.27.1",
"squizlabs/php_codesniffer": "4.0.1",
"symfony/cache": "^6.3.8|^7.0|^8.0",
"symfony/console": "^5.4|^6.3|^7.0|^8.0"
"symfony/console": "^5.4|^6.3|^7.0|^8.0",
"symfony/service-contracts": "^2|^3"
},
"suggest": {
"symfony/console": "For helpful console commands such as SQL execution and import of files."
Expand Down
17 changes: 17 additions & 0 deletions src/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
use Doctrine\DBAL\Driver\Middleware;
use Doctrine\DBAL\Exception\InvalidArgumentException;
use Doctrine\DBAL\Schema\SchemaManagerFactory;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\TypeRegistry;
use Psr\Cache\CacheItemPoolInterface;

/**
Expand Down Expand Up @@ -36,6 +38,8 @@ class Configuration

private ?SchemaManagerFactory $schemaManagerFactory = null;

private ?TypeRegistry $typeRegistry = null;

public function __construct()
{
$this->schemaAssetsFilter = static function (): bool {
Expand Down Expand Up @@ -134,6 +138,19 @@ public function setSchemaManagerFactory(SchemaManagerFactory $schemaManagerFacto
return $this;
}

public function getTypeRegistry(): TypeRegistry
{
return $this->typeRegistry ??= Type::getTypeRegistry();
}

/** @return $this */
public function setTypeRegistry(TypeRegistry $typeRegistry): self
{
$this->typeRegistry = $typeRegistry;

return $this;
}

public function getDisableTypeComments(): bool
{
return true;
Expand Down
8 changes: 5 additions & 3 deletions src/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,7 @@ public function getDatabasePlatform(): AbstractPlatform
}

$this->platform = $this->driver->getDatabasePlatform($versionProvider);
$this->platform->setConfiguration($this->_config);
}

return $this->platform;
Expand Down Expand Up @@ -1278,7 +1279,8 @@ public function isRollbackOnly(): bool
*/
public function convertToDatabaseValue(mixed $value, string $type): mixed
{
return Type::getType($type)->convertToDatabaseValue($value, $this->getDatabasePlatform());
return $this->_config->getTypeRegistry()->get($type)
->convertToDatabaseValue($value, $this->getDatabasePlatform());
}

/**
Expand All @@ -1294,7 +1296,7 @@ public function convertToDatabaseValue(mixed $value, string $type): mixed
*/
public function convertToPHPValue(mixed $value, string $type): mixed
{
return Type::getType($type)->convertToPHPValue($value, $this->getDatabasePlatform());
return $this->_config->getTypeRegistry()->get($type)->convertToPHPValue($value, $this->getDatabasePlatform());
}

/**
Expand Down Expand Up @@ -1360,7 +1362,7 @@ private function bindParameters(DriverStatement $stmt, array $params, array $typ
private function getBindingInfo(mixed $value, string|ParameterType|Type $type): array
{
if (is_string($type)) {
$type = Type::getType($type);
$type = $this->_config->getTypeRegistry()->get($type);
}

if ($type instanceof Type) {
Expand Down
20 changes: 17 additions & 3 deletions src/Platforms/AbstractPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Doctrine\DBAL\Platforms;

use Doctrine\DBAL\Configuration;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Exception;
use Doctrine\DBAL\Exception\InvalidArgumentException;
Expand Down Expand Up @@ -107,6 +108,8 @@ abstract class AbstractPlatform
*/
private ?UnquotedIdentifierFolding $unquotedIdentifierFolding = null;

private ?Configuration $configuration = null;

public function __construct(?UnquotedIdentifierFolding $unquotedIdentifierFolding = null)
{
if ($unquotedIdentifierFolding === null) {
Expand All @@ -121,6 +124,17 @@ public function __construct(?UnquotedIdentifierFolding $unquotedIdentifierFoldin
$this->unquotedIdentifierFolding = $unquotedIdentifierFolding ?? UnquotedIdentifierFolding::UPPER;
}

/** @internal Called by Connection after platform creation. */
public function setConfiguration(Configuration $configuration): void
{
$this->configuration = $configuration;
}

private function getTypeRegistry(): Types\TypeRegistry
{
return $this->configuration?->getTypeRegistry() ?? Type::getTypeRegistry();
}

/**
* Returns the SQL snippet that declares a boolean column.
*
Expand Down Expand Up @@ -171,8 +185,8 @@ private function initializeAllDoctrineTypeMappings(): void
{
$this->initializeDoctrineTypeMappings();

foreach (Type::getTypesMap() as $typeName => $className) {
foreach (Type::getType($typeName)->getMappedDatabaseTypes($this) as $dbType) {
foreach ($this->getTypeRegistry()->getMap() as $typeName => $type) {
foreach ($type->getMappedDatabaseTypes($this) as $dbType) {
$dbType = strtolower($dbType);
$this->doctrineTypeMapping[$dbType] = $typeName;
}
Expand Down Expand Up @@ -397,7 +411,7 @@ public function registerDoctrineTypeMapping(string $dbType, string $doctrineType
$this->initializeAllDoctrineTypeMappings();
}

if (! Types\Type::hasType($doctrineType)) {
if (! $this->getTypeRegistry()->has($doctrineType)) {
throw TypeNotFound::new($doctrineType);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Platforms/Db2/Db2MetadataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ private function createTableColumn(array $row): TableColumnMetadataRow
}

$editor
->setTypeName($type)
->setType($this->connection->getConfiguration()->getTypeRegistry()->get($type))
->setNotNull($nulls === 'N')
->setDefaultValue($this->parseDefaultExpression($default))
->setAutoincrement($generated === 'D');
Expand Down
6 changes: 4 additions & 2 deletions src/Platforms/MySQL/MySQLMetadataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -214,8 +214,10 @@ private function createTableColumn(array $row): TableColumnMetadataRow

$editor = Column::editor()
->setQuotedName($columnName)
->setTypeName(
$this->platform->getDoctrineTypeMapping($dbType),
->setType(
$this->connection->getConfiguration()->getTypeRegistry()->get(
$this->platform->getDoctrineTypeMapping($dbType),
),
);

if (str_contains($columnType, 'unsigned')) {
Expand Down
2 changes: 1 addition & 1 deletion src/Platforms/Oracle/OracleMetadataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ private function createTableColumn(array $row): TableColumnMetadataRow
}

$editor
->setTypeName($type)
->setType($this->connection->getConfiguration()->getTypeRegistry()->get($type))
->setPrecision($precision)
->setScale($scale)
->setNotNull($nullable === 'N')
Expand Down
6 changes: 4 additions & 2 deletions src/Platforms/PostgreSQL/PostgreSQLMetadataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,10 @@ private function createTableColumn(array $row): TableColumnMetadataRow
$completeType = $domainCompleteType;
}

$editor->setTypeName(
$this->platform->getDoctrineTypeMapping($typeName),
$editor->setType(
$this->connection->getConfiguration()->getTypeRegistry()->get(
$this->platform->getDoctrineTypeMapping($typeName),
),
);

switch ($typeName) {
Expand Down
6 changes: 4 additions & 2 deletions src/Platforms/SQLServer/SQLServerMetadataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -221,8 +221,10 @@ private function createTableColumn(array $row): TableColumnMetadataRow

$editor = Column::editor()
->setQuotedName($columnName)
->setTypeName(
$this->platform->getDoctrineTypeMapping($dbType),
->setType(
$this->connection->getConfiguration()->getTypeRegistry()->get(
$this->platform->getDoctrineTypeMapping($dbType),
),
)
->setNotNull(! $isNullable)
->setAutoincrement((bool) $isIdentity);
Expand Down
2 changes: 1 addition & 1 deletion src/Platforms/SQLite/SQLiteMetadataProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ private function createTableColumn(array $row, array $sqlByTableName): TableColu

$typeName = $this->platform->getDoctrineTypeMapping($dbType);

$editor->setTypeName($typeName);
$editor->setType($this->connection->getConfiguration()->getTypeRegistry()->get($typeName));

if ($dbType === 'char') {
$editor->setFixed(true);
Expand Down
13 changes: 13 additions & 0 deletions src/Schema/AbstractSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Doctrine\DBAL\Schema\Name\Parsers;
use Doctrine\DBAL\Schema\Name\UnqualifiedName;
use Doctrine\DBAL\Types\Exception\TypesException;
use Doctrine\DBAL\Types\Type;
use Doctrine\Deprecations\Deprecation;
use Throwable;

Expand Down Expand Up @@ -264,6 +265,8 @@ public function listTables(): array
$this->_getPortableTableForeignKeysList($foreignKeyColumnsByTable[$tableName] ?? []),
$tableOptionsByTable[$tableName] ?? [],
$configuration,
null,
$this->connection->getConfiguration()->getTypeRegistry(),
);
}

Expand Down Expand Up @@ -494,6 +497,9 @@ public function introspectTable(string $name): Table
[],
$this->listTableForeignKeys($name),
$this->getTableOptions($name),
null,
null,
$this->connection->getConfiguration()->getTypeRegistry(),
);
}

Expand Down Expand Up @@ -1267,6 +1273,12 @@ protected function _getPortableSequenceDefinition(array $sequence): Sequence
throw NotSupported::new(__METHOD__);
}

/** @throws TypesException */
final protected function getType(string $typeName): Type
{
return $this->connection->getConfiguration()->getTypeRegistry()->get($typeName);
}

/**
* Independent of the database the keys of the column list result are lowercased.
*
Expand Down Expand Up @@ -1444,6 +1456,7 @@ public function createSchemaConfig(): SchemaConfig
}

$schemaConfig->setDefaultTableOptions($params['defaultTableOptions']);
$schemaConfig->setTypeRegistry($this->connection->getConfiguration()->getTypeRegistry());

return $schemaConfig;
}
Expand Down
7 changes: 7 additions & 0 deletions src/Schema/ColumnDiff.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,13 @@ public function hasNameChanged(): bool

public function hasTypeChanged(): bool
{
// TODO: This comparison by class is insufficient now that types can be distinct services sharing the same
// class (e.g. two differently configured instances of the same Type subclass). It also produces false
// negatives for built-in aliases that share a class: json and json_object both map to JsonType::class,
// so switching between them is not detected as a change.
// The fix is to compare Type instances by identity (===) once both the introspected schema and the
// target schema are guaranteed to resolve types from the same TypeRegistry, so the flyweight invariant
// (one instance per registered name) holds across both sides of the diff.
return $this->newColumn->getType()::class !== $this->oldColumn->getType()::class;
}

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

use Doctrine\DBAL\Platforms\DB2Platform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;

use function array_change_key_case;
Expand Down Expand Up @@ -98,7 +97,7 @@ protected function _getPortableTableColumnDefinition(array $tableColumn): Column
$options['precision'] = $precision;
}

return new Column($tableColumn['colname'], Type::getType($type), $options);
return new Column($tableColumn['colname'], $this->getType($type), $options);
}

/**
Expand Down
3 changes: 1 addition & 2 deletions src/Schema/MySQLSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
use Doctrine\DBAL\Schema\DefaultExpression\CurrentDate;
use Doctrine\DBAL\Schema\DefaultExpression\CurrentTime;
use Doctrine\DBAL\Schema\DefaultExpression\CurrentTimestamp;
use Doctrine\DBAL\Types\Type;

use function array_change_key_case;
use function array_map;
Expand Down Expand Up @@ -214,7 +213,7 @@ protected function _getPortableTableColumnDefinition(array $tableColumn): Column
$options['comment'] = $tableColumn['comment'];
}

$column = new Column($tableColumn['field'], Type::getType($type), $options);
$column = new Column($tableColumn['field'], $this->getType($type), $options);
$column->setPlatformOption('charset', $tableColumn['characterset']);
$column->setPlatformOption('collation', $tableColumn['collation']);

Expand Down
3 changes: 1 addition & 2 deletions src/Schema/OracleSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use Doctrine\DBAL\Exception\DatabaseObjectNotFoundException;
use Doctrine\DBAL\Platforms\OraclePlatform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Types\Type;

use function array_change_key_case;
use function array_key_exists;
Expand Down Expand Up @@ -184,7 +183,7 @@ protected function _getPortableTableColumnDefinition(array $tableColumn): Column
$options['comment'] = $tableColumn['comments'];
}

return new Column($this->getQuotedIdentifierName($tableColumn['column_name']), Type::getType($type), $options);
return new Column($this->getQuotedIdentifierName($tableColumn['column_name']), $this->getType($type), $options);
}

/**
Expand Down
3 changes: 1 addition & 2 deletions src/Schema/PostgreSQLSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Types\JsonType;
use Doctrine\DBAL\Types\Type;

use function array_change_key_case;
use function array_map;
Expand Down Expand Up @@ -274,7 +273,7 @@ protected function _getPortableTableColumnDefinition(array $tableColumn): Column
$options['comment'] = $tableColumn['comment'];
}

$column = new Column($tableColumn['field'], Type::getType($type), $options);
$column = new Column($tableColumn['field'], $this->getType($type), $options);

if (! empty($tableColumn['collation'])) {
$column->setPlatformOption('collation', $tableColumn['collation']);
Expand Down
3 changes: 1 addition & 2 deletions src/Schema/SQLServerSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
use Doctrine\DBAL\Platforms\SQLServerPlatform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Schema\DefaultExpression\CurrentTimestamp;
use Doctrine\DBAL\Types\Type;

use function array_change_key_case;
use function assert;
Expand Down Expand Up @@ -132,7 +131,7 @@ protected function _getPortableTableColumnDefinition(array $tableColumn): Column
$options['length'] = $length;
}

$column = new Column($tableColumn['name'], Type::getType($type), $options);
$column = new Column($tableColumn['name'], $this->getType($type), $options);

if ($tableColumn['default'] !== null) {
$default = $this->parseDefaultExpression($tableColumn['default']);
Expand Down
3 changes: 1 addition & 2 deletions src/Schema/SQLiteSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use Doctrine\DBAL\Platforms\SQLite;
use Doctrine\DBAL\Platforms\SQLitePlatform;
use Doctrine\DBAL\Result;
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Types\Types;
use Doctrine\Deprecations\Deprecation;

Expand Down Expand Up @@ -127,7 +126,7 @@ protected function _getPortableTableColumnDefinition(array $tableColumn): Column
'scale' => $scale,
];

$column = new Column($tableColumn['name'], Type::getType($type), $options);
$column = new Column($tableColumn['name'], $this->getType($type), $options);

if ($type === Types::STRING || $type === Types::TEXT) {
$column->setPlatformOption('collation', $tableColumn['collation'] ?? 'BINARY');
Expand Down
12 changes: 11 additions & 1 deletion src/Schema/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,17 @@ public function createNamespace(string $name): self
*/
public function createTable(string $name): Table
{
$table = new Table($name, [], [], [], [], [], $this->_schemaConfig->toTableConfiguration());
$table = new Table(
$name,
[],
[],
[],
[],
[],
$this->_schemaConfig->toTableConfiguration(),
null,
$this->_schemaConfig->getTypeRegistry(),
);
$this->_addTable($table);

foreach ($this->_schemaConfig->getDefaultTableOptions() as $option => $value) {
Expand Down
Loading
Loading