Skip to content

Commit

Permalink
Merge pull request #6660 from morozov/table-editor
Browse files Browse the repository at this point in the history
Introduce table editor
  • Loading branch information
morozov authored Dec 22, 2024
2 parents e7e2615 + e51fd97 commit 03049bc
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 25 deletions.
5 changes: 5 additions & 0 deletions UPGRADE.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ awareness about deprecated code.

# Upgrade to 4.3

## `Table::__construct()` marked as internal

The `Table::__construct()` method has been marked as internal. Use `Table::editor()` to instantiate an editor and
`TableEditor::create()` to create a table.

## Deprecated `AbstractAsset::getShortestName()`

The `AbstractAsset::getShortestName()` method has been deprecated. Use `AbstractAsset::getName()` instead.
Expand Down
44 changes: 27 additions & 17 deletions src/Schema/AbstractSchemaManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -210,15 +210,26 @@ public function listTables(): array
continue;
}

$tables[] = new Table(
$tableName,
$this->_getPortableTableColumnList($tableName, $database, $tableColumns),
$this->_getPortableTableIndexesList($indexColumnsByTable[$tableName] ?? [], $tableName),
[],
$this->_getPortableTableForeignKeysList($foreignKeyColumnsByTable[$tableName] ?? []),
$tableOptionsByTable[$tableName] ?? [],
$configuration,
);
$editor = Table::editor()
->setName($tableName)
->setColumns($this->_getPortableTableColumnList($tableName, $database, $tableColumns))
->setIndexes(
$this->_getPortableTableIndexesList($indexColumnsByTable[$tableName] ?? [], $tableName),
);

if (isset($foreignKeyColumnsByTable[$tableName])) {
$editor->setForeignKeyConstraints(
$this->_getPortableTableForeignKeysList($foreignKeyColumnsByTable[$tableName]),
);
}

if (isset($tableOptionsByTable[$tableName])) {
$editor->setOptions($tableOptionsByTable[$tableName]);
}

$tables[] = $editor
->setConfiguration($configuration)
->create();
}

return $tables;
Expand Down Expand Up @@ -328,14 +339,13 @@ public function introspectTable(string $name): Table
throw TableDoesNotExist::new($name);
}

return new Table(
$name,
$columns,
$this->listTableIndexes($name),
[],
$this->listTableForeignKeys($name),
$this->getTableOptions($name),
);
return Table::editor()
->setName($name)
->setColumns($columns)
->setIndexes($this->listTableIndexes($name))
->setForeignKeyConstraints($this->listTableForeignKeys($name))
->setOptions($this->getTableOptions($name))
->create();
}

/**
Expand Down
17 changes: 17 additions & 0 deletions src/Schema/Exception/InvalidTableDefinition.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Schema\Exception;

use Doctrine\DBAL\Schema\SchemaException;
use LogicException;

/** @psalm-immutable */
final class InvalidTableDefinition extends LogicException implements SchemaException
{
public static function nameNotSet(): self
{
return new self('Table name is not set.');
}
}
3 changes: 1 addition & 2 deletions src/Schema/Name.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ interface Name
/**
* Returns the string representation of the name.
*
* The consumers of this method should not rely on a specific return value. It should be used only for diagnostic
* purposes.
* If passed to the corresponding parser, the name should be parsed back to an equivalent object.
*/
public function toString(): string;
}
11 changes: 6 additions & 5 deletions src/Schema/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -283,12 +283,13 @@ public function createNamespace(string $name): self
*/
public function createTable(string $name): Table
{
$table = new Table($name, [], [], [], [], [], $this->_schemaConfig->toTableConfiguration());
$this->_addTable($table);
$table = Table::editor()
->setName($name)
->setOptions($this->_schemaConfig->getDefaultTableOptions())
->setConfiguration($this->_schemaConfig->toTableConfiguration())
->create();

foreach ($this->_schemaConfig->getDefaultTableOptions() as $option => $value) {
$table->addOption($option, $value);
}
$this->_addTable($table);

return $table;
}
Expand Down
28 changes: 28 additions & 0 deletions src/Schema/Table.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ class Table extends AbstractNamedObject
private int $maxIdentifierLength;

/**
* @internal Use {@link Table::editor()} to instantiate an editor and {@link TableEditor::create()}
* to create a table.
*
* @param array<Column> $columns
* @param array<Index> $indexes
* @param array<UniqueConstraint> $uniqueConstraints
Expand Down Expand Up @@ -847,6 +850,31 @@ public function getComment(): ?string
return $this->_options['comment'] ?? null;
}

/**
* Instantiates a new table editor.
*/
public static function editor(): TableEditor
{
return new TableEditor();
}

/**
* Instantiates a new table editor and initializes it with the table's properties.
*/
public function edit(): TableEditor
{
return self::editor()
->setName($this->getObjectName()->toString())
->setColumns($this->_columns)
->setIndexes($this->_indexes)
->setUniqueConstraints($this->uniqueConstraints)
->setForeignKeyConstraints($this->_fkConstraints)
->setOptions($this->_options)
->setConfiguration(
new TableConfiguration($this->maxIdentifierLength),
);
}

/**
* @param array<string|int, string> $columns
* @param array<int, string> $flags
Expand Down
2 changes: 1 addition & 1 deletion src/Schema/TableConfiguration.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
/**
* Contains platform-specific parameters used for creating and managing objects scoped to a {@see Table}.
*/
class TableConfiguration
final class TableConfiguration
{
/** @internal The configuration can be only instantiated by a {@see SchemaConfig}. */
public function __construct(private readonly int $maxIdentifierLength)
Expand Down
105 changes: 105 additions & 0 deletions src/Schema/TableEditor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Schema;

use Doctrine\DBAL\Schema\Exception\InvalidTableDefinition;

final class TableEditor
{
private ?string $name = null;

/** @var array<Column> */
private array $columns = [];

/** @var array<Index> */
private array $indexes = [];

/** @var array<UniqueConstraint> */
private array $uniqueConstraints = [];

/** @var array<ForeignKeyConstraint> */
private array $foreignKeyConstraints = [];

/** @var array<string, mixed> */
private array $options = [];

private ?TableConfiguration $configuration = null;

/** @internal Use {@link Table::editor()} or {@link Table::edit()} to create an instance */
public function __construct()
{
}

public function setName(string $name): self
{
$this->name = $name;

return $this;
}

/** @param array<Column> $columns */
public function setColumns(array $columns): self
{
$this->columns = $columns;

return $this;
}

/** @param array<Index> $indexes */
public function setIndexes(array $indexes): self
{
$this->indexes = $indexes;

return $this;
}

/** @param array<UniqueConstraint> $uniqueConstraints */
public function setUniqueConstraints(array $uniqueConstraints): self
{
$this->uniqueConstraints = $uniqueConstraints;

return $this;
}

/** @param array<ForeignKeyConstraint> $foreignKeyConstraints */
public function setForeignKeyConstraints(array $foreignKeyConstraints): self
{
$this->foreignKeyConstraints = $foreignKeyConstraints;

return $this;
}

/** @param array<string, mixed> $options */
public function setOptions(array $options): self
{
$this->options = $options;

return $this;
}

public function setConfiguration(TableConfiguration $configuration): self
{
$this->configuration = $configuration;

return $this;
}

public function create(): Table
{
if ($this->name === null) {
throw InvalidTableDefinition::nameNotSet();
}

return new Table(
$this->name,
$this->columns,
$this->indexes,
$this->uniqueConstraints,
$this->foreignKeyConstraints,
$this->options,
$this->configuration,
);
}
}
29 changes: 29 additions & 0 deletions tests/Schema/TableEditorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Doctrine\DBAL\Tests\Schema;

use Doctrine\DBAL\Schema\Exception\InvalidTableDefinition;
use Doctrine\DBAL\Schema\Table;
use PHPUnit\Framework\TestCase;

class TableEditorTest extends TestCase
{
public function testSetName(): void
{
$table = (new Table('accounts'))
->edit()
->setName('contacts')
->create();

self::assertSame('contacts', $table->getName());
}

public function testNameNotSet(): void
{
$this->expectException(InvalidTableDefinition::class);

Table::editor()->create();
}
}

0 comments on commit 03049bc

Please sign in to comment.