*/ private array $columns = []; private bool $isClustered = false; /** @var ?non-empty-string */ private ?string $predicate = null; /** @internal Use {@link Index::editor()} or {@link Index::edit()} to create an instance */ public function __construct() { } public function setName(?UnqualifiedName $name): self { $this->name = $name; return $this; } /** @param non-empty-string $name */ public function setUnquotedName(string $name): self { $this->name = UnqualifiedName::unquoted($name); return $this; } /** @param non-empty-string $name */ public function setQuotedName(string $name): self { $this->name = UnqualifiedName::quoted($name); return $this; } public function setType(IndexType $type): self { $this->type = $type; return $this; } public function setColumns(IndexedColumn $firstColumn, IndexedColumn ...$otherColumns): self { $this->columns = [$firstColumn, ...array_values($otherColumns)]; return $this; } public function addColumn(IndexedColumn $column): self { $this->columns[] = $column; return $this; } public function setColumnNames(UnqualifiedName $firstColumnName, UnqualifiedName ...$otherColumnNames): self { $this->columns = array_map( static fn (UnqualifiedName $name) => new IndexedColumn($name, null), [$firstColumnName, ...array_values($otherColumnNames)], ); return $this; } /** * @param non-empty-string $firstColumnName * @param non-empty-string ...$otherColumnNames */ public function setUnquotedColumnNames( string $firstColumnName, string ...$otherColumnNames, ): self { $this->columns = array_map( static fn (string $name): IndexedColumn => new IndexedColumn(UnqualifiedName::unquoted($name), null), [$firstColumnName, ...array_values($otherColumnNames)], ); return $this; } /** * @param non-empty-string $firstColumnName * @param non-empty-string ...$otherColumnNames */ public function setQuotedColumnNames( string $firstColumnName, string ...$otherColumnNames, ): self { $this->columns = array_map( static fn (string $name): IndexedColumn => new IndexedColumn(UnqualifiedName::quoted($name), null), [$firstColumnName, ...array_values($otherColumnNames)], ); return $this; } public function setIsClustered(bool $isClustered): self { $this->isClustered = $isClustered; return $this; } /** @param ?non-empty-string $predicate */ public function setPredicate(?string $predicate): self { $this->predicate = $predicate; return $this; } public function create(): Index { if ($this->name === null) { throw InvalidIndexDefinition::nameNotSet(); } if (count($this->columns) < 1) { throw InvalidIndexDefinition::columnsNotSet($this->name); } $columnNames = $lengths = $options = $flags = []; foreach ($this->columns as $i => $column) { $columnNames[] = $column->getColumnName()->toString(); $length = $column->getLength(); if ($length === null) { continue; } $lengths[$i] = $column->getLength(); } if (count($lengths) !== 0) { $options['lengths'] = $lengths; } if ($this->type === IndexType::FULLTEXT) { $flags[] = 'fulltext'; } elseif ($this->type === IndexType::SPATIAL) { $flags[] = 'spatial'; } if ($this->isClustered) { $flags[] = 'clustered'; } if ($this->predicate !== null) { $options['where'] = $this->predicate; } return new Index( $this->name->toString(), $columnNames, $this->type === IndexType::UNIQUE, false, $flags, $options, ); } }