final class UpsertUpdate

What an UPSERT does to a row it found a conflict on.

Two questions have to be answered about every conflict: whether the statement goes on to update the row at all, and what the row looks like once it has. Both depend on where the assignment was worked out — the database can evaluate an expression against the row as it stood, but not against a row this same statement changed a moment ago, and then the expression has to be read here or the statement refused.

Type Aliases§

Row = import from TableDefinition
RowValue = import from TableDefinition

Methods§

public function __construct(
    private string $tableName,
    private array<int, string> $primaryKeys,
    private array<int, string> $updateColumns,
    private array<string, UpsertExpression|null> $updateValues,
    private array<string, string> $updateSqlValues,
    private string|null $updateSqlPredicate,
    private UpsertExpression|null $updatePredicate,
    private bool $databaseEvaluated,
    private UpsertMutationRow $codec = new \ZtdQuery\Shadow\Mutation\UpsertMutationRow(),
)

Parameters

$tableNamestringTable being written to
$primaryKeysarray<int, string>Columns a conflict is found on
$updateColumnsarray<int, string>Columns the statement assigns to
$updateValuesarray<string, UpsertExpression|null>What each column is assigned, as ZTD reads it
$updateSqlValuesarray<string, string>What each column is assigned, as the statement wrote it
$updateSqlPredicatestring|nullCondition on the update, as the statement wrote it
$updatePredicateUpsertExpression|nullCondition on the update, as ZTD reads it
$databaseEvaluatedboolWhether the database worked the assignments out already
$codecUpsertMutationRowReads what the database worked out off a row
Test cases 14
Calls 1
public function incomingRow(Row $row): Row

Answers the row the statement was trying to write.

Parameters

$rowRowRow as it arrived, carrying what the database worked out

Returns

Row The row the statement wrote, without any of that
Test cases 2
Called from 1
Calls 2
public function applies(
    Row $row,
    Row $existingRow,
    Row $incomingRow,
    bool $changedEarlier,
): bool

Reports whether the statement goes on to update the row it conflicted with.

Parameters

$rowRowRow as it arrived, carrying what the database worked out
$existingRowRowRow the conflict was found on
$incomingRowRowRow the statement was trying to write
$changedEarlierboolWhether this same statement already changed the row

Returns

bool True when the row is one the statement updates

Throws

UnsupportedSqlException When the condition has to be read here and cannot be
Test cases 5
Called from 1
Calls 4
public function of(Row $row, Row $existingRow, Row $incomingRow, bool $changedEarlier): Row

Answers the row as the statement leaves it.

A statement that names no column to assign carries everything it was writing over, except what the conflict was found on, which is what makes it the same row.

Parameters

$rowRowRow as it arrived, carrying what the database worked out
$existingRowRowRow the conflict was found on
$incomingRowRowRow the statement was trying to write
$changedEarlierboolWhether this same statement already changed the row

Returns

Row The updated row

Throws

UnsupportedSqlException When an assignment has to be read here and cannot be
Test cases 2
Called from 1
Calls 2
public function withColumn(
    Row $updatedRow,
    string $column,
    int $index,
    Row $row,
    Row $incomingRow,
    bool $changedEarlier,
): Row

Answers the row with one column assigned as the statement asked.

A column the database already worked out is taken from what it worked out; a column it could not is read here, against the row as this statement has left it so far, which is what makes assignments written over one another read in the order they were written.

Parameters

$updatedRowRowRow as the statement has left it so far
$columnstringColumn being assigned
$indexintWhich of the assigned columns this is
$rowRowRow as it arrived, carrying what the database worked out
$incomingRowRowRow the statement was trying to write
$changedEarlierboolWhether this same statement already changed the row

Returns

Row The row with that column assigned

Throws

UnsupportedSqlException When the assignment has to be read here and cannot be
Test cases 4
Called from 1
Calls 3
public function predicateRead(string $reason): UpsertExpression
public function valueRead(string $column, string $reason): UpsertExpression

Answers what a column is assigned as ZTD reads it, insisting it could be read.

Parameters

$columnstringColumn being assigned
$reasonstringWhy it has to be read here rather than by the database

Returns

UpsertExpression The assignment

Throws

UnsupportedSqlException When the statement wrote an assignment ZTD cannot read
Test cases 2
Called from 2
Calls 1

Private surface 9§

Implementation details, listed for orientation only.

private string $tableName
private array<int, string> $primaryKeys
private array<int, string> $updateColumns
private array<string, UpsertExpression|null> $updateValues
private array<string, string> $updateSqlValues
private string|null $updateSqlPredicate
private UpsertExpression|null $updatePredicate
private bool $databaseEvaluated
private UpsertMutationRow $codec = new \ZtdQuery\Shadow\Mutation\UpsertMutationRow()

Test cases 16§

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

Dedicated tests 14
Other tests reaching this symbol 2

Relations§

Instantiated in 1
Method calls 3
Type declarations 1