*/ private array $referencingColumnNames = []; private ?OptionallyQualifiedName $referencedTableName = null; /** @var list */ private array $referencedColumnNames = []; private MatchType $matchType = MatchType::SIMPLE; private ReferentialAction $onUpdateAction = ReferentialAction::NO_ACTION; private ReferentialAction $onDeleteAction = ReferentialAction::NO_ACTION; private Deferrability $deferrability = Deferrability::NOT_DEFERRABLE; /** * @internal Use {@link ForeignKeyConstraint::editor()} or {@link ForeignKeyConstraint::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 setReferencingColumnNames( UnqualifiedName $firstColumnName, UnqualifiedName ...$otherColumnNames, ): self { $this->referencingColumnNames = [$firstColumnName, ...array_values($otherColumnNames)]; return $this; } /** * @param non-empty-string $firstColumnName * @param non-empty-string ...$otherColumnNames */ public function setUnquotedReferencingColumnNames( string $firstColumnName, string ...$otherColumnNames, ): self { $this->referencingColumnNames = array_map( static fn (string $name): UnqualifiedName => UnqualifiedName::unquoted($name), [$firstColumnName, ...array_values($otherColumnNames)], ); return $this; } /** * @param non-empty-string $firstColumnName * @param non-empty-string ...$otherColumnNames */ public function setQuotedReferencingColumnNames( string $firstColumnName, string ...$otherColumnNames, ): self { $this->referencingColumnNames = array_map( static fn (string $name): UnqualifiedName => UnqualifiedName::quoted($name), [$firstColumnName, ...array_values($otherColumnNames)], ); return $this; } public function addReferencingColumnName(UnqualifiedName $columName): self { $this->referencingColumnNames[] = $columName; return $this; } public function setReferencedTableName(OptionallyQualifiedName $referencedTableName): self { $this->referencedTableName = $referencedTableName; return $this; } /** * @param non-empty-string $unqualifiedReferencedTableName * @param ?non-empty-string $referencedTableNameQualifier */ public function setUnquotedReferencedTableName( string $unqualifiedReferencedTableName, ?string $referencedTableNameQualifier = null, ): self { $this->referencedTableName = OptionallyQualifiedName::unquoted($unqualifiedReferencedTableName, $referencedTableNameQualifier); return $this; } /** * @param non-empty-string $unqualifiedReferencedTableName * @param ?non-empty-string $referencedTableNameQualifier */ public function setQuotedReferencedTableName( string $unqualifiedReferencedTableName, ?string $referencedTableNameQualifier = null, ): self { $this->referencedTableName = OptionallyQualifiedName::quoted($unqualifiedReferencedTableName, $referencedTableNameQualifier); return $this; } public function setReferencedColumnNames( UnqualifiedName $firstColumnName, UnqualifiedName ...$otherColumnNames, ): self { $this->referencedColumnNames = [$firstColumnName, ...array_values($otherColumnNames)]; return $this; } /** * @param non-empty-string $firstColumnName * @param non-empty-string ...$otherColumnNames */ public function setUnquotedReferencedColumnNames( string $firstColumnName, string ...$otherColumnNames, ): self { $this->referencedColumnNames = array_map( static fn (string $name): UnqualifiedName => UnqualifiedName::unquoted($name), [$firstColumnName, ...array_values($otherColumnNames)], ); return $this; } /** * @param non-empty-string $firstColumnName * @param non-empty-string ...$otherColumnNames */ public function setQuotedReferencedColumnNames( string $firstColumnName, string ...$otherColumnNames, ): self { $this->referencedColumnNames = array_map( static fn (string $name): UnqualifiedName => UnqualifiedName::quoted($name), [$firstColumnName, ...array_values($otherColumnNames)], ); return $this; } public function addReferencedColumnName(UnqualifiedName $columName): self { $this->referencedColumnNames[] = $columName; return $this; } public function setMatchType(MatchType $matchType): self { $this->matchType = $matchType; return $this; } public function setOnUpdateAction(ReferentialAction $action): self { $this->onUpdateAction = $action; return $this; } public function setOnDeleteAction(ReferentialAction $action): self { $this->onDeleteAction = $action; return $this; } public function setDeferrability(Deferrability $deferrability): self { $this->deferrability = $deferrability; return $this; } public function create(): ForeignKeyConstraint { if (count($this->referencingColumnNames) < 1) { throw InvalidForeignKeyConstraintDefinition::referencingColumnNamesNotSet($this->name); } if ($this->referencedTableName === null) { throw InvalidForeignKeyConstraintDefinition::referencedTableNameNotSet($this->name); } if (count($this->referencedColumnNames) < 1) { throw InvalidForeignKeyConstraintDefinition::referencedColumnNamesNotSet($this->name); } $options = []; if ($this->matchType !== MatchType::SIMPLE) { $options['match'] = $this->matchType->value; } if ($this->onUpdateAction !== ReferentialAction::NO_ACTION) { $options['onUpdate'] = $this->onUpdateAction->value; } if ($this->onDeleteAction !== ReferentialAction::NO_ACTION) { $options['onDelete'] = $this->onDeleteAction->value; } return new ForeignKeyConstraint( array_map( static fn (UnqualifiedName $columnName) => $columnName->toString(), $this->referencingColumnNames, ), $this->referencedTableName->toString(), array_map( static fn (UnqualifiedName $columnName) => $columnName->toString(), $this->referencedColumnNames, ), $this->name?->toString() ?? '', array_merge($options, match ($this->deferrability) { Deferrability::NOT_DEFERRABLE => [], Deferrability::DEFERRABLE => ['deferrable' => true], Deferrability::DEFERRED => ['deferrable' => true, 'deferred' => true], }), ); } }