Skip to content

Commit

Permalink
feat: Add insertOrUpdateUsingMutation
Browse files Browse the repository at this point in the history
+ change ManagesMutations private methods to protected.
  • Loading branch information
r4m-alexd committed Jun 13, 2023
1 parent f43cda3 commit 3e6dee3
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 3 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

Added
- Added deprecation warnings to `Connection::runDdl` and `Connection::runDdls` (#98)
- Added `ManagesMutations::insertOrUpdateUsingMutation` and `UsesMutations::insertOrUpdateUsingMutation` to do upserts (#109)

Changed
- `Connection::waitForOperation` and `Connection::isDoneOperation` has been removed. (#99)
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ You can [insert, update, and delete data using mutations](https://cloud.google.c
```
$queryBuilder->insertUsingMutation($values);
$queryBuilder->updateUsingMutation($values);
$queryBuilder->insertOrUpdateUsingMutation($values);
$queryBuilder->deleteUsingMutation($values);
```

Expand Down
20 changes: 17 additions & 3 deletions src/Concerns/ManagesMutations.php
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@ public function updateUsingMutation(string $table, array $dataSet)
});
}

/**
* @param string $table
* @param array<string, mixed> $dataSet
* @return void
*/
public function insertOrUpdateUsingMutation(string $table, array $dataSet)
{
$this->withTransactionEvents(function () use ($table, $dataSet) {
$dataSet = $this->prepareForMutation($dataSet);
$this->event(new MutatingData($this, $table, 'update', $dataSet));
$this->getDatabaseContext()->insertOrUpdateBatch($table, $dataSet);
});
}

/**
* @param string $table
* @param scalar|array<mixed>|KeySet $keySet
Expand All @@ -78,7 +92,7 @@ public function deleteUsingMutation(string $table, $keySet)
* @param callable $mutationCall
* @return void
*/
private function withTransactionEvents(callable $mutationCall)
protected function withTransactionEvents(callable $mutationCall)
{
// events not necessary since it is already called
if ($this->inTransaction()) {
Expand All @@ -94,7 +108,7 @@ private function withTransactionEvents(callable $mutationCall)
* @param array $dataSet
* @return array
*/
private function prepareForMutation(array $dataSet): array
protected function prepareForMutation(array $dataSet): array
{
if (empty($dataSet)) {
return [];
Expand All @@ -119,7 +133,7 @@ private function prepareForMutation(array $dataSet): array
* @param mixed|list<string>|KeySet $keys
* @return KeySet
*/
private function createDeleteMutationKeySet($keys)
protected function createDeleteMutationKeySet($keys)
{
if ($keys instanceof KeySet) {
return $keys;
Expand Down
9 changes: 9 additions & 0 deletions src/Query/Concerns/UsesMutations.php
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@ public function updateUsingMutation(array $values)
$this->connection->updateUsingMutation($this->from, $values);
}

/**
* @param array<string, mixed> $values
* @return void
*/
public function insertOrUpdateUsingMutation(array $values)
{
$this->connection->insertOrUpdateUsingMutation($this->from, $values);
}

/**
* @param array|KeySet $keys
* @return void
Expand Down
45 changes: 45 additions & 0 deletions tests/ConnectionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,51 @@ public function testUpdateUsingMutationWithoutTransaction(): void
Event::assertDispatchedTimes(TransactionCommitted::class, 2);
}

public function testInsertOrUpdateUsingMutationWithTransaction(): void
{
Event::fake();

$userId1 = $this->generateUuid();
$userId2 = $this->generateUuid();
$conn = $this->getDefaultConnection();

$conn->insertUsingMutation(self::TABLE_NAME_USER, ['userId' => $userId1, 'name' => 'test1']);

$conn->transaction(function () use ($conn, $userId1, $userId2) {
$conn->insertOrUpdateUsingMutation(self::TABLE_NAME_USER, [
['userId' => $userId1, 'name' => 'tester1'],
['userId' => $userId2, 'name' => 'tester2'],
]);
});

$this->assertEquals(['userId' => $userId1, 'name' => 'tester1'], $conn->table(self::TABLE_NAME_USER)->where('userId', $userId1)->first());
$this->assertEquals(['userId' => $userId2, 'name' => 'tester2'], $conn->table(self::TABLE_NAME_USER)->where('userId', $userId2)->first());
Event::assertDispatchedTimes(TransactionBeginning::class, 2);
Event::assertDispatchedTimes(MutatingData::class, 2);
Event::assertDispatchedTimes(TransactionCommitted::class, 2);
}

public function testInsertOrUpdateUsingMutationWithoutTransaction(): void
{
Event::fake();

$userId1 = $this->generateUuid();
$userId2 = $this->generateUuid();
$conn = $this->getDefaultConnection();

$conn->insertUsingMutation(self::TABLE_NAME_USER, ['userId' => $userId1, 'name' => 'test1']);
$conn->insertOrUpdateUsingMutation(self::TABLE_NAME_USER, [
['userId' => $userId1, 'name' => 'tester1'],
['userId' => $userId2, 'name' => 'tester2'],
]);

$this->assertEquals(['userId' => $userId1, 'name' => 'tester1'], $conn->table(self::TABLE_NAME_USER)->where('userId', $userId1)->first());
$this->assertEquals(['userId' => $userId2, 'name' => 'tester2'], $conn->table(self::TABLE_NAME_USER)->where('userId', $userId2)->first());
Event::assertDispatchedTimes(TransactionBeginning::class, 2);
Event::assertDispatchedTimes(MutatingData::class, 2);
Event::assertDispatchedTimes(TransactionCommitted::class, 2);
}

public function testDeleteUsingMutationWithTransaction(): void
{
Event::fake();
Expand Down

0 comments on commit 3e6dee3

Please sign in to comment.