classUpsertUpdate
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 TableDefinitionRowValue = import from TableDefinitionMethods§
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
$tableName | string | Table being written to |
$primaryKeys | array<int, string> | Columns a conflict is found on |
$updateColumns | array<int, string> | Columns the statement assigns to |
$updateValues | array<string, UpsertExpression|null> | What each column is assigned, as ZTD reads it |
$updateSqlValues | array<string, string> | What each column is assigned, as the statement wrote it |
$updateSqlPredicate | string|null | Condition on the update, as the statement wrote it |
$updatePredicate | UpsertExpression|null | Condition on the update, as ZTD reads it |
$databaseEvaluated | bool | Whether the database worked the assignments out already |
$codec | UpsertMutationRow | Reads what the database worked out off a row |
Test cases 14
UpsertUpdateTest::testAppliesReadsTheConditionHereWhereTheDatabaseWorkedNothingOutcoversUpsertUpdateTest::testAppliesRefusesAConditionTheDatabaseCouldNotWorkOutForARowAlreadyChangedcoversUpsertUpdateTest::testAppliesRefusesAConditionTheDatabaseDidNotWorkOutAtAllcoversUpsertUpdateTest::testAppliesTakesTheVerdictTheDatabaseWorkedOutcoversUpsertUpdateTest::testAppliesToEveryConflictWhereTheStatementWroteNoConditioncoversUpsertUpdateTest::testIncomingRowLeavesARowAloneWhereTheDatabaseWorkedNothingOutcoversUpsertUpdateTest::testIncomingRowTakesOffWhatTheDatabaseWorkedOutcoversUpsertUpdateTest::testOfAssignsEachColumnTheStatementNamescoversUpsertUpdateTest::testOfCarriesEverythingButTheConflictColumnsWhereNoColumnIsNamedcoversUpsertUpdateTest::testPredicateReadRefusesAConditionZtdCouldNotReadcoversUpsertUpdateTest::testValueReadAnswersTheAssignmentZtdReadcoversUpsertUpdateTest::testWithColumnReadsTheExpressionAgainstTheRowAsTheStatementLeftItcoversUpsertUpdateTest::testWithColumnRefusesAnAssignmentTheDatabaseCouldNotWorkOutcoversUpsertUpdateTest::testWithColumnTakesWhatTheDatabaseWorkedOutcovers
Calls 1
Answers the row the statement was trying to write.
Parameters
$row | Row | Row as it arrived, carrying what the database worked out |
Returns
Row The row the statement wrote, without any of thatTest cases 2
Called from 1
Calls 2
- method-call UpsertMutationRow::incomingRow() line 59
- function-call
countline 59
public function applies(
Row $row,
Row $existingRow,
Row $incomingRow,
bool $changedEarlier,
): boolReports whether the statement goes on to update the row it conflicted with.
Parameters
Returns
bool True when the row is one the statement updatesThrows
UnsupportedSqlException When the condition has to be read here and cannot beTest cases 5
UpsertUpdateTest::testAppliesReadsTheConditionHereWhereTheDatabaseWorkedNothingOutcovers and callsUpsertUpdateTest::testAppliesRefusesAConditionTheDatabaseCouldNotWorkOutForARowAlreadyChangedcovers and callsUpsertUpdateTest::testAppliesRefusesAConditionTheDatabaseDidNotWorkOutAtAllcovers and callsUpsertUpdateTest::testAppliesTakesTheVerdictTheDatabaseWorkedOutcovers and callsUpsertUpdateTest::testAppliesToEveryConflictWhereTheStatementWroteNoConditioncovers and calls
Called from 1
Calls 4
- method-call UpsertUpdate::predicateRead() line 82
- function-call
array_key_existsline 85 - method-call UpsertMutationRow::predicateColumn() line 85
- method-call UpsertMutationRow::predicateMatches() line 86
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
Returns
Row The updated rowThrows
UnsupportedSqlException When an assignment has to be read here and cannot beTest cases 2
Called from 1
Calls 2
- method-call UpsertUpdate::withColumn() line 115
- function-call
in_arrayline 121
public function withColumn(
Row $updatedRow,
string $column,
int $index,
Row $row,
Row $incomingRow,
bool $changedEarlier,
): RowAnswers 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
$updatedRow | Row | Row as the statement has left it so far |
$column | string | Column being assigned |
$index | int | Which of the assigned columns this is |
$row | Row | Row as it arrived, carrying what the database worked out |
$incomingRow | Row | Row the statement was trying to write |
$changedEarlier | bool | Whether this same statement already changed the row |
Returns
Row The row with that column assignedThrows
UnsupportedSqlException When the assignment has to be read here and cannot beTest cases 4
UpsertUpdateTest::testOfAssignsEachColumnTheStatementNamescoversUpsertUpdateTest::testWithColumnReadsTheExpressionAgainstTheRowAsTheStatementLeftItcovers and callsUpsertUpdateTest::testWithColumnRefusesAnAssignmentTheDatabaseCouldNotWorkOutcovers and callsUpsertUpdateTest::testWithColumnTakesWhatTheDatabaseWorkedOutcovers and calls
Called from 1
Calls 3
- method-call UpsertMutationRow::valueColumn() line 167
- method-call UpsertUpdate::valueRead() line 169
- function-call
array_key_existsline 171
public function predicateRead(string $reason): UpsertExpressionAnswers the condition as ZTD reads it, insisting it could be read.
Parameters
$reason | string | Why it has to be read here rather than by the database |
Returns
UpsertExpression The conditionThrows
UnsupportedSqlException When the statement wrote a condition ZTD cannot readTest cases 3
Called from 2
Calls 1
public function valueRead(string $column, string $reason): UpsertExpressionAnswers what a column is assigned as ZTD reads it, insisting it could be read.
Parameters
$column | string | Column being assigned |
$reason | string | Why it has to be read here rather than by the database |
Returns
UpsertExpression The assignmentThrows
UnsupportedSqlException When the statement wrote an assignment ZTD cannot readTest cases 2
Called from 2
Calls 1
Private surface 9§
Implementation details, listed for orientation only.
private string $tableNameprivate array<int, string> $primaryKeysprivate array<int, string> $updateColumnsprivate array<string, UpsertExpression|null> $updateValuesprivate array<string, string> $updateSqlValuesprivate string|null $updateSqlPredicateprivate UpsertExpression|null $updatePredicateprivate bool $databaseEvaluatedprivate 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
UpsertUpdateTest::testAppliesReadsTheConditionHereWhereTheDatabaseWorkedNothingOutcovers and callsUpsertUpdateTest::testAppliesRefusesAConditionTheDatabaseCouldNotWorkOutForARowAlreadyChangedcovers and callsUpsertUpdateTest::testAppliesRefusesAConditionTheDatabaseDidNotWorkOutAtAllcovers and callsUpsertUpdateTest::testAppliesTakesTheVerdictTheDatabaseWorkedOutcovers and callsUpsertUpdateTest::testAppliesToEveryConflictWhereTheStatementWroteNoConditioncovers and callsUpsertUpdateTest::testIncomingRowLeavesARowAloneWhereTheDatabaseWorkedNothingOutcovers and callsUpsertUpdateTest::testIncomingRowTakesOffWhatTheDatabaseWorkedOutcovers and callsUpsertUpdateTest::testOfAssignsEachColumnTheStatementNamescovers and callsUpsertUpdateTest::testOfCarriesEverythingButTheConflictColumnsWhereNoColumnIsNamedcovers and callsUpsertUpdateTest::testPredicateReadRefusesAConditionZtdCouldNotReadcovers and callsUpsertUpdateTest::testValueReadAnswersTheAssignmentZtdReadcovers and callsUpsertUpdateTest::testWithColumnReadsTheExpressionAgainstTheRowAsTheStatementLeftItcovers and callsUpsertUpdateTest::testWithColumnRefusesAnAssignmentTheDatabaseCouldNotWorkOutcovers and callsUpsertUpdateTest::testWithColumnTakesWhatTheDatabaseWorkedOutcovers and calls
Other tests reaching this symbol 2
MutationImpactTestcallsUpsertMutationTestcalls
Relations§
Instantiated in 1
Method calls 3
- method-call ZtdQuery\Shadow\Mutation\UpsertMutation::apply() packages/ztd-query-core/src/Shadow/Mutation/UpsertMutation.php:124
- method-call ZtdQuery\Shadow\Mutation\UpsertMutation::apply() packages/ztd-query-core/src/Shadow/Mutation/UpsertMutation.php:136
- method-call ZtdQuery\Shadow\Mutation\UpsertMutation::apply() packages/ztd-query-core/src/Shadow/Mutation/UpsertMutation.php:140