From cc64018130c74a2d0184625b61a3b7bd8324dc3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 22 Jul 2024 14:30:10 +0200 Subject: [PATCH] Fix incrementEach to handle null values --- src/Query/Builder.php | 18 ++++++------------ tests/QueryBuilderTest.php | 4 ++-- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 73c73a7a3..ddc2413d8 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -789,24 +789,18 @@ public function increment($column, $amount = 1, array $extra = [], array $option public function incrementEach(array $columns, array $extra = [], array $options = []) { - $query = ['$inc' => $columns]; + $stage['$addFields'] = $extra; - if ($extra) { - $query['$set'] = $extra; - } - - // Protect + // Not using $inc for each column, because it would fail if one column is null. foreach ($columns as $column => $amount) { - $this->where(function ($query) use ($column) { - $query->where($column, 'exists', false); - - $query->orWhereNotNull($column); - }); + $stage['$addFields'][$column] = [ + '$add' => [$amount, ['$ifNull' => ['$' . $column, 0]]], + ]; } $options = $this->inheritConnectionOptions($options); - return $this->performUpdate($query, $options); + return $this->performUpdate([$stage], $options); } /** @inheritdoc */ diff --git a/tests/QueryBuilderTest.php b/tests/QueryBuilderTest.php index 947b84b93..d819db5cd 100644 --- a/tests/QueryBuilderTest.php +++ b/tests/QueryBuilderTest.php @@ -1020,8 +1020,8 @@ public function testIncrementEach() $this->assertEquals(8, $user['note']); $user = DB::collection('users')->where('name', 'Robert Roe')->first(); - $this->assertNull($user['age']); - $this->assertArrayNotHasKey('note', $user); + $this->assertSame(1, $user['age']); + $this->assertSame(2, $user['note']); DB::collection('users')->where('name', 'Jane Doe')->incrementEach([ 'age' => 1,