From bf6655a534a6775d30cafa67bd801276bda1d98d Mon Sep 17 00:00:00 2001 From: polo Date: Tue, 13 Aug 2024 23:45:21 +0200 Subject: =?UTF-8?q?VERSION=200.2=20doctrine=20ORM=20et=20entit=C3=A9s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- vendor/doctrine/dbal/src/Schema/Index.php | 314 ++++++++++++++++++++++++++++++ 1 file changed, 314 insertions(+) create mode 100644 vendor/doctrine/dbal/src/Schema/Index.php (limited to 'vendor/doctrine/dbal/src/Schema/Index.php') diff --git a/vendor/doctrine/dbal/src/Schema/Index.php b/vendor/doctrine/dbal/src/Schema/Index.php new file mode 100644 index 0000000..1755654 --- /dev/null +++ b/vendor/doctrine/dbal/src/Schema/Index.php @@ -0,0 +1,314 @@ + + */ + protected array $_columns = []; + + protected bool $_isUnique = false; + + protected bool $_isPrimary = false; + + /** + * Platform specific flags for indexes. + * + * @var array + */ + protected array $_flags = []; + + /** + * @param array $columns + * @param array $flags + * @param array $options + */ + public function __construct( + ?string $name, + array $columns, + bool $isUnique = false, + bool $isPrimary = false, + array $flags = [], + private readonly array $options = [], + ) { + $isUnique = $isUnique || $isPrimary; + + if ($name !== null) { + $this->_setName($name); + } + + $this->_isUnique = $isUnique; + $this->_isPrimary = $isPrimary; + + foreach ($columns as $column) { + $this->_addColumn($column); + } + + foreach ($flags as $flag) { + $this->addFlag($flag); + } + } + + protected function _addColumn(string $column): void + { + $this->_columns[$column] = new Identifier($column); + } + + /** + * Returns the names of the referencing table columns the constraint is associated with. + * + * @return list + */ + public function getColumns(): array + { + return array_keys($this->_columns); + } + + /** + * Returns the quoted representation of the column names the constraint is associated with. + * + * But only if they were defined with one or a column name + * is a keyword reserved by the platform. + * Otherwise, the plain unquoted value as inserted is returned. + * + * @param AbstractPlatform $platform The platform to use for quotation. + * + * @return list + */ + public function getQuotedColumns(AbstractPlatform $platform): array + { + $subParts = $platform->supportsColumnLengthIndexes() && $this->hasOption('lengths') + ? $this->getOption('lengths') : []; + + $columns = []; + + foreach ($this->_columns as $column) { + $length = array_shift($subParts); + + $quotedColumn = $column->getQuotedName($platform); + + if ($length !== null) { + $quotedColumn .= '(' . $length . ')'; + } + + $columns[] = $quotedColumn; + } + + return $columns; + } + + /** @return array */ + public function getUnquotedColumns(): array + { + return array_map($this->trimQuotes(...), $this->getColumns()); + } + + /** + * Is the index neither unique nor primary key? + */ + public function isSimpleIndex(): bool + { + return ! $this->_isPrimary && ! $this->_isUnique; + } + + public function isUnique(): bool + { + return $this->_isUnique; + } + + public function isPrimary(): bool + { + return $this->_isPrimary; + } + + public function hasColumnAtPosition(string $name, int $pos = 0): bool + { + $name = $this->trimQuotes(strtolower($name)); + $indexColumns = array_map('strtolower', $this->getUnquotedColumns()); + + return array_search($name, $indexColumns, true) === $pos; + } + + /** + * Checks if this index exactly spans the given column names in the correct order. + * + * @param array $columnNames + */ + public function spansColumns(array $columnNames): bool + { + $columns = $this->getColumns(); + $numberOfColumns = count($columns); + $sameColumns = true; + + for ($i = 0; $i < $numberOfColumns; $i++) { + if ( + isset($columnNames[$i]) + && $this->trimQuotes(strtolower($columns[$i])) === $this->trimQuotes(strtolower($columnNames[$i])) + ) { + continue; + } + + $sameColumns = false; + } + + return $sameColumns; + } + + /** + * Checks if the other index already fulfills all the indexing and constraint needs of the current one. + */ + public function isFulfilledBy(Index $other): bool + { + // allow the other index to be equally large only. It being larger is an option + // but it creates a problem with scenarios of the kind PRIMARY KEY(foo,bar) UNIQUE(foo) + if (count($other->getColumns()) !== count($this->getColumns())) { + return false; + } + + // Check if columns are the same, and even in the same order + $sameColumns = $this->spansColumns($other->getColumns()); + + if ($sameColumns) { + if (! $this->samePartialIndex($other)) { + return false; + } + + if (! $this->hasSameColumnLengths($other)) { + return false; + } + + if (! $this->isUnique() && ! $this->isPrimary()) { + // this is a special case: If the current key is neither primary or unique, any unique or + // primary key will always have the same effect for the index and there cannot be any constraint + // overlaps. This means a primary or unique index can always fulfill the requirements of just an + // index that has no constraints. + return true; + } + + if ($other->isPrimary() !== $this->isPrimary()) { + return false; + } + + return $other->isUnique() === $this->isUnique(); + } + + return false; + } + + /** + * Detects if the other index is a non-unique, non primary index that can be overwritten by this one. + */ + public function overrules(Index $other): bool + { + if ($other->isPrimary()) { + return false; + } + + if ($this->isSimpleIndex() && $other->isUnique()) { + return false; + } + + return $this->spansColumns($other->getColumns()) + && ($this->isPrimary() || $this->isUnique()) + && $this->samePartialIndex($other); + } + + /** + * Returns platform specific flags for indexes. + * + * @return array + */ + public function getFlags(): array + { + return array_keys($this->_flags); + } + + /** + * Adds Flag for an index that translates to platform specific handling. + * + * @example $index->addFlag('CLUSTERED') + */ + public function addFlag(string $flag): self + { + $this->_flags[strtolower($flag)] = true; + + return $this; + } + + /** + * Does this index have a specific flag? + */ + public function hasFlag(string $flag): bool + { + return isset($this->_flags[strtolower($flag)]); + } + + /** + * Removes a flag. + */ + public function removeFlag(string $flag): void + { + unset($this->_flags[strtolower($flag)]); + } + + public function hasOption(string $name): bool + { + return isset($this->options[strtolower($name)]); + } + + public function getOption(string $name): mixed + { + return $this->options[strtolower($name)]; + } + + /** @return array */ + public function getOptions(): array + { + return $this->options; + } + + /** + * Return whether the two indexes have the same partial index + */ + private function samePartialIndex(Index $other): bool + { + if ( + $this->hasOption('where') + && $other->hasOption('where') + && $this->getOption('where') === $other->getOption('where') + ) { + return true; + } + + return ! $this->hasOption('where') && ! $other->hasOption('where'); + } + + /** + * Returns whether the index has the same column lengths as the other + */ + private function hasSameColumnLengths(self $other): bool + { + $filter = static function (?int $length): bool { + return $length !== null; + }; + + return array_filter($this->options['lengths'] ?? [], $filter) + === array_filter($other->options['lengths'] ?? [], $filter); + } +} -- cgit v1.2.3