From ab58ffd39fb98fd47f7161a0095b8cdc812b2f9e Mon Sep 17 00:00:00 2001 From: zhenghongyang Date: Thu, 21 Nov 2019 23:55:22 +0800 Subject: [PATCH] compatible group count --- src/db/src/Concern/HasAttributes.php | 2 +- src/db/src/Eloquent/Model.php | 5 +- src/db/src/Query/Builder.php | 10 ++++ src/db/test/unit/Eloquent/ModelTest.php | 67 ++++++++++++++++++++++++- 4 files changed, 79 insertions(+), 5 deletions(-) diff --git a/src/db/src/Concern/HasAttributes.php b/src/db/src/Concern/HasAttributes.php index 8eaf2c2c7..3c652fa18 100644 --- a/src/db/src/Concern/HasAttributes.php +++ b/src/db/src/Concern/HasAttributes.php @@ -524,7 +524,7 @@ public function syncOriginal(): self /** * Sync a single original attribute with its current value. * - * @param string $attribute + * @param string|array $attribute * * @return $this */ diff --git a/src/db/src/Eloquent/Model.php b/src/db/src/Eloquent/Model.php index 8335b3f91..bb03ab14a 100644 --- a/src/db/src/Eloquent/Model.php +++ b/src/db/src/Eloquent/Model.php @@ -459,7 +459,7 @@ public function syncCounter(array $counters, array $extra = []): self if ($extra) { // Sync extra - $this->fill($extra); + $this->setRawAttributes($extra, true); } return $this; @@ -604,8 +604,7 @@ protected function setKeysForSaveQuery(Builder $query) */ protected function getKeyForSaveQuery() { - return $this->modelOriginal[$this->getKeyName()] - ?? $this->getKey(); + return $this->modelOriginal[$this->getKeyName()] ?? $this->getKey(); } /** diff --git a/src/db/src/Query/Builder.php b/src/db/src/Query/Builder.php index 8dd780b01..49d185e6e 100644 --- a/src/db/src/Query/Builder.php +++ b/src/db/src/Query/Builder.php @@ -2748,6 +2748,11 @@ public function aggregate(string $function, array $columns = ['*']) ->get($columns); if (!$results->isEmpty()) { + // Compatible group aggregate + if (isset($this->groups)) { + return $results->pluck('aggregate')->$function(); + } + return array_change_key_case((array)$results[0])['aggregate']; } @@ -3073,6 +3078,11 @@ public function warpCounters(array $counters): array { // Convert counters to expression foreach ($counters as $column => $value) { + if (empty($value)) { + unset($counters[$column]); + continue; + } + if (!$value instanceof Expression) { $wrapped = $this->grammar->wrap($column); diff --git a/src/db/test/unit/Eloquent/ModelTest.php b/src/db/test/unit/Eloquent/ModelTest.php index 811b119c5..286101fed 100644 --- a/src/db/test/unit/Eloquent/ModelTest.php +++ b/src/db/test/unit/Eloquent/ModelTest.php @@ -709,8 +709,9 @@ public function testUpdateAllCounters() $this->assertEquals($user->getAge() - 1, User::find($id)->getAge()); $user = User::find($id); - $user->updateCounters(['age' => -1]); + $user->updateCounters(['age' => -1], ['udesc' => 'swoft']); + $this->assertEquals([], $user->getDirty()); $this->assertEquals($user->getAge(), User::find($id)->getAge()); } @@ -877,4 +878,68 @@ public function testFindOrFail() $this->expectException(DbException::class); $user->update(['age' => 2]); } + + public function testDirty(): void + { + $origin = ['age' => 1, 'name' => 'swoft']; + User::updateOrCreate(['id' => 1], $origin); + + $user = User::find(1); + + $dirty = $user->getDirty(); + // No changes + $this->assertEquals([], $dirty); + + + $user->setAge(2); + $dirty = $user->getDirty(); + // Change age to 2 + $this->assertEquals(['age' => 2], $dirty); + + + $user->setName('swoft2'); + $dirty = $user->getDirty(); + // Change name to swoft2 + $this->assertEquals(['age' => 2, 'name' => 'swoft2'], $dirty); + + + // recovery changes + $fillOrigin = $user->fill($origin)->getDirty(); + $this->assertEquals([], $fillOrigin); + + // setter + $user->setModelAttribute('name', 'on'); + $dirty = $user->getDirty(); + $this->assertEquals(['name' => 'on'], $dirty); + } + + public function testGroupAggregate(): void + { + User::truncate(); + + $origin = ['age' => 1, 'user_desc' => 'swoft']; + $origin2 = ['age' => 2, 'user_desc' => 'swoft2']; + + User::updateOrCreate(['id' => 1], $origin); + User::updateOrCreate(['id' => 2], $origin2); + User::updateOrCreate(['id' => 3], $origin2); + + $count = User::groupBy('user_desc')->count(); + + $this->assertEquals(2, $count); + + $originCount = User::count(); + $this->assertEquals(3, $originCount); + + $minAge = User::groupBy('age')->min('age'); + $this->assertEquals(1, $minAge); + $this->assertEquals(1, User::min('age')); + + $maxAge = User::groupBy('age')->max('age'); + $this->assertEquals(2, $maxAge); + $this->assertEquals(2, User::max('age')); + + $this->assertEquals(1.6667, User::avg('age')); + $this->assertEquals(1.5, User::groupBy('age')->avg('age')); + } }