Skip to content

Commit 33f5589

Browse files
authored
Merge pull request #6550 from morozov/implicit-index-names
Simplify tracking implicitly created indexes
2 parents 6322f42 + 960f849 commit 33f5589

File tree

3 files changed

+53
-24
lines changed

3 files changed

+53
-24
lines changed

phpcs.xml.dist

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,7 @@
102102

103103
<!-- See https://github.com/squizlabs/PHP_CodeSniffer/issues/2837 -->
104104
<rule ref="Squiz.NamingConventions.ValidVariableName.NotCamelCaps">
105-
<exclude-pattern>src/Connection.php</exclude-pattern>
106-
<exclude-pattern>src/Schema/Comparator.php</exclude-pattern>
107-
<exclude-pattern>src/SQLParserUtils.php</exclude-pattern>
105+
<exclude-pattern>src/Schema/Table.php</exclude-pattern>
108106
</rule>
109107

110108
<!-- some statement classes close cursor using an empty while-loop -->
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\DBAL\Schema\Exception;
6+
7+
use Doctrine\DBAL\Schema\SchemaException;
8+
use LogicException;
9+
10+
use function sprintf;
11+
12+
/** @psalm-immutable */
13+
final class PrimaryKeyAlreadyExists extends LogicException implements SchemaException
14+
{
15+
public static function new(string $tableName): self
16+
{
17+
return new self(
18+
sprintf('Primary key was already defined on table "%s".', $tableName),
19+
);
20+
}
21+
}

src/Schema/Table.php

Lines changed: 31 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
use Doctrine\DBAL\Schema\Exception\IndexDoesNotExist;
1212
use Doctrine\DBAL\Schema\Exception\IndexNameInvalid;
1313
use Doctrine\DBAL\Schema\Exception\InvalidTableName;
14+
use Doctrine\DBAL\Schema\Exception\PrimaryKeyAlreadyExists;
1415
use Doctrine\DBAL\Schema\Exception\UniqueConstraintDoesNotExist;
1516
use Doctrine\DBAL\Types\Type;
1617
use LogicException;
1718

1819
use function array_merge;
1920
use function array_values;
20-
use function in_array;
2121
use function preg_match;
2222
use function sprintf;
2323
use function strtolower;
@@ -30,15 +30,20 @@ class Table extends AbstractAsset
3030
/** @var Column[] */
3131
protected array $_columns = [];
3232

33-
/** @var Index[] */
34-
private array $implicitIndexes = [];
35-
3633
/** @var array<string, string> keys are new names, values are old names */
3734
protected array $renamedColumns = [];
3835

3936
/** @var Index[] */
4037
protected array $_indexes = [];
4138

39+
/**
40+
* The keys of this array are the names of the indexes that were implicitly created as backing for foreign key
41+
* constraints. The values are not used but must be non-null for {@link isset()} to work correctly.
42+
*
43+
* @var array<string,true>
44+
*/
45+
private array $implicitIndexNames = [];
46+
4247
protected ?string $_primaryKeyName = null;
4348

4449
/** @var UniqueConstraint[] */
@@ -606,36 +611,41 @@ protected function _addColumn(Column $column): void
606611
/**
607612
* Adds an index to the table.
608613
*/
609-
protected function _addIndex(Index $indexCandidate): self
614+
protected function _addIndex(Index $index): self
610615
{
611-
$indexName = $indexCandidate->getName();
612-
$indexName = $this->normalizeIdentifier($indexName);
613-
$replacedImplicitIndexes = [];
616+
$indexName = $this->normalizeIdentifier($index->getName());
614617

615-
foreach ($this->implicitIndexes as $name => $implicitIndex) {
616-
if (! $implicitIndex->isFulfilledBy($indexCandidate) || ! isset($this->_indexes[$name])) {
618+
$replacedImplicitIndexNames = [];
619+
620+
foreach ($this->implicitIndexNames as $implicitIndexName => $_) {
621+
if (! isset($this->_indexes[$implicitIndexName])) {
622+
continue;
623+
}
624+
625+
if (! $this->_indexes[$implicitIndexName]->isFulfilledBy($index)) {
617626
continue;
618627
}
619628

620-
$replacedImplicitIndexes[] = $name;
629+
$replacedImplicitIndexNames[$implicitIndexName] = true;
621630
}
622631

623-
if (
624-
(isset($this->_indexes[$indexName]) && ! in_array($indexName, $replacedImplicitIndexes, true)) ||
625-
($this->_primaryKeyName !== null && $indexCandidate->isPrimary())
626-
) {
632+
if (isset($this->_indexes[$indexName]) && ! isset($replacedImplicitIndexNames[$indexName])) {
627633
throw IndexAlreadyExists::new($indexName, $this->_name);
628634
}
629635

630-
foreach ($replacedImplicitIndexes as $name) {
631-
unset($this->_indexes[$name], $this->implicitIndexes[$name]);
636+
if ($this->_primaryKeyName !== null && $index->isPrimary()) {
637+
throw PrimaryKeyAlreadyExists::new($this->_name);
638+
}
639+
640+
foreach ($replacedImplicitIndexNames as $name => $_) {
641+
unset($this->_indexes[$name], $this->implicitIndexNames[$name]);
632642
}
633643

634-
if ($indexCandidate->isPrimary()) {
644+
if ($index->isPrimary()) {
635645
$this->_primaryKeyName = $indexName;
636646
}
637647

638-
$this->_indexes[$indexName] = $indexCandidate;
648+
$this->_indexes[$indexName] = $index;
639649

640650
return $this;
641651
}
@@ -671,7 +681,7 @@ protected function _addUniqueConstraint(UniqueConstraint $constraint): self
671681
}
672682
}
673683

674-
$this->implicitIndexes[$this->normalizeIdentifier($indexName)] = $indexCandidate;
684+
$this->implicitIndexNames[$this->normalizeIdentifier($indexName)] = true;
675685

676686
return $this;
677687
}
@@ -709,7 +719,7 @@ protected function _addForeignKeyConstraint(ForeignKeyConstraint $constraint): s
709719
}
710720

711721
$this->_addIndex($indexCandidate);
712-
$this->implicitIndexes[$this->normalizeIdentifier($indexName)] = $indexCandidate;
722+
$this->implicitIndexNames[$this->normalizeIdentifier($indexName)] = true;
713723

714724
return $this;
715725
}

0 commit comments

Comments
 (0)