final class ForeignKeyCascade

Applies to one child table what happened to its parent.

A parent row that moved only reaches its children where nothing else holds the key up, so each candidate is checked against the parent table first. An update carries new values to write; a delete carries none, and the action decides whether the child goes with it, is set to null, or refuses the statement outright.

What comes back is what happened to the child table, in the same shape as what happened to the parent, which is what lets the caller keep following the constraints outward without knowing how deep it is.

Type Aliases§

Row = import from TableDefinition
RowValue = import from TableDefinition

Methods§

public function __construct(
    private ForeignKeyEnds $ends,
    private ParentKeyLookup $parents = new \ZtdQuery\Shadow\ParentKeyLookup(),
    private RowMatch $rows = new \ZtdQuery\Shadow\Row\RowMatch(),
)
public function of(
    ShadowStore $store,
    string $childTable,
    string $constraintName,
    ForeignKeyDefinition $foreignKey,
    TableTransition $parent,
    string $sql,
): TableTransition|null

Answers what one constraint makes of what happened to the parent.

Parameters

$storeShadowStoreShadow the child rows live in, written back in place
$childTablestringTable holding the key
$constraintNamestringConstraint being followed, for the refusal
$foreignKeyForeignKeyDefinitionConstraint being followed
$parentTableTransitionWhat happened to the parent table
$sqlstringStatement being simulated, for the refusal

Returns

TableTransition|null What happened to the child, or null when nothing did

Throws

ForeignKeyViolationException When the action forbids the statement
Test cases 4
Called from 1
Calls 14
public function carryUpdate(
    CascadedChildren $children,
    ShadowStore $store,
    FollowedConstraint $constraint,
    list<string> $referencedColumns,
    RowChange $parentChange,
): void

Carries a parent row that moved to the children that were holding it.

A key the parent table still holds up somewhere else has not moved as far as the child is concerned, so nothing is carried for it.

Parameters

$childrenCascadedChildrenChild rows as the cascade has left them
$storeShadowStoreShadow the parent rows live in
$constraintFollowedConstraintConstraint being followed
$referencedColumnslist<string>Parent columns the key points at
$parentChangeRowChangeWhat happened to the one parent row

Throws

ForeignKeyViolationException When the action forbids the statement
Test cases 3
Called from 1
Calls 6
public function carryDelete(
    CascadedChildren $children,
    ShadowStore $store,
    FollowedConstraint $constraint,
    list<string> $referencedColumns,
    Row $parentRow,
): void
public function applyAction(
    Row $row,
    list<RowValue> $values,
    ReferentialAction $action,
    FollowedConstraint $constraint,
): Row

Writes into a child row what the declared action says should be there.

Only CASCADE and SET NULL let the statement stand. Every other action — RESTRICT, NO ACTION, SET DEFAULT — means the parent was not free to move, so the statement is refused rather than quietly rewritten.

Parameters

$rowRowChild row to rewrite
$valueslist<RowValue>Values to carry over, empty when the parent went
$actionReferentialActionAction the constraint declares
$constraintFollowedConstraintConstraint being followed, for the refusal

Returns

Row The child row as it should now be

Throws

ForeignKeyViolationException When the action forbids the statement
Test cases 6
Called from 2
Calls 4

Private surface 3§

Implementation details, listed for orientation only.

private ForeignKeyEnds $ends
private ParentKeyLookup $parents = new \ZtdQuery\Shadow\ParentKeyLookup()
private RowMatch $rows = new \ZtdQuery\Shadow\Row\RowMatch()

Test cases 16§

Test cases that cover or call this symbol, from the coverage report and from the analyzed test sources.

Dedicated tests 12
Other tests reaching this symbol 4

Relations§

Instantiated in 1
Method calls 1