Skip to content

Commit

Permalink
Merge branch '3.7.x' into 4.0.x
Browse files Browse the repository at this point in the history
* 3.7.x:
  Optimize TypeRegistry::lookupName() from O(N) to O(1) (doctrine#6082)
  Add documentation for doctrine#6044 (doctrine#6069)
  Use triggerIfCalledFromOutside in listTableDetails
  Document alternative to Type::getName (doctrine#6077)
  • Loading branch information
derrabus committed Jul 15, 2023
2 parents 6982657 + b30518d commit c2a3fea
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 8 deletions.
4 changes: 3 additions & 1 deletion UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -1567,11 +1567,13 @@ This method is unused by the DBAL since 2.0.

## Deprecated `Type::getName()`

This will method is not useful for the DBAL anymore, and will be removed in 4.0.
This method is not useful for the DBAL anymore, and will be removed in 4.0.
As a consequence, depending on the name of a type being `json` for `jsonb` to
be used for the Postgres platform is deprecated in favor of extending
`Doctrine\DBAL\Types\JsonType`.

You can use `Type::getTypeRegistry()->lookupName($type)` instead.

## Deprecated `AbstractPlatform::getColumnComment()`, `AbstractPlatform::getDoctrineTypeComment()`,
`AbstractPlatform::hasNative*Type()` and `Type::requiresSQLCommentHint()`

Expand Down
19 changes: 19 additions & 0 deletions docs/en/reference/schema-representation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,25 @@ All schema assets reside in the ``Doctrine\DBAL\Schema`` namespace.

This chapter is far from being completely documented.

Table
~~~~~~

Represents a table in the schema.

Vendor specific options
^^^^^^^^^^^^^^^^^^^^^^^

The following options, that can be set using ``default_table_options``, are completely vendor specific
and absolutely not portable.

- **charset** (string): The character set to use for the table. Currently only supported
on MySQL.

- **engine** (string): The DB engine used for the table. Currently only supported on MySQL.

- **unlogged** (boolean): Set a PostgreSQL table type as
`unlogged <https://www.postgresql.org/docs/current/sql-createtable.htmll>`_

Column
~~~~~~

Expand Down
38 changes: 31 additions & 7 deletions src/Types/TypeRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,26 @@
use Doctrine\DBAL\Types\Exception\TypesAlreadyExists;
use Doctrine\DBAL\Types\Exception\UnknownColumnType;

use function array_search;
use function spl_object_id;

/**
* The type registry is responsible for holding a map of all known DBAL types.
*/
final class TypeRegistry
{
/** @var array<string, Type> Map of type names and their corresponding flyweight objects. */
private array $instances;
/** @var array<int, string> */
private array $instancesReverseIndex;

/** @param array<string, Type> $instances */
public function __construct(private array $instances = [])
public function __construct(array $instances = [])
{
$this->instances = [];
$this->instancesReverseIndex = [];
foreach ($instances as $name => $type) {
$this->register($name, $type);
}
}

/**
Expand All @@ -29,11 +39,12 @@ public function __construct(private array $instances = [])
*/
public function get(string $name): Type
{
if (! isset($this->instances[$name])) {
$type = $this->instances[$name] ?? null;
if ($type === null) {
throw UnknownColumnType::new($name);
}

return $this->instances[$name];
return $type;
}

/**
Expand Down Expand Up @@ -71,7 +82,8 @@ public function register(string $name, Type $type): void
throw TypesAlreadyExists::new($name);
}

$this->instances[$name] = $type;
$this->instances[$name] = $type;
$this->instancesReverseIndex[spl_object_id($type)] = $name;
}

/**
Expand All @@ -81,11 +93,18 @@ public function register(string $name, Type $type): void
*/
public function override(string $name, Type $type): void
{
if (! isset($this->instances[$name])) {
$origType = $this->instances[$name] ?? null;
if ($origType === null) {
throw TypeNotFound::new($name);
}

$this->instances[$name] = $type;
if (($this->findTypeName($type) ?? $name) !== $name) {
throw TypesAlreadyExists::new($name);
}

unset($this->instancesReverseIndex[spl_object_id($origType)]);
$this->instances[$name] = $type;
$this->instancesReverseIndex[spl_object_id($type)] = $name;
}

/**
Expand All @@ -99,4 +118,9 @@ public function getMap(): array
{
return $this->instances;
}

private function findTypeName(Type $type): ?string
{
return $this->instancesReverseIndex[spl_object_id($type)] ?? null;
}
}
8 changes: 8 additions & 0 deletions tests/Types/TypeRegistryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,14 @@ public function testRegisterWithAlreadyRegisteredInstance(): void
);
}

public function testConstructorWithDuplicateInstance(): void
{
$newType = new TextType();

$this->expectException(Exception::class);
new TypeRegistry(['a' => $newType, 'b' => $newType]);
}

public function testOverride(): void
{
$baseType = new TextType();
Expand Down

0 comments on commit c2a3fea

Please sign in to comment.