From 4ec7a5f3e9a76c4b297f6ec45a5f1a731dab31ae Mon Sep 17 00:00:00 2001 From: David Date: Sun, 27 Mar 2022 17:48:19 +0700 Subject: [PATCH 1/6] Fix whereDate, whereMonth, whereYear, whereTime to use $expr and respective query rather than using basic comparison --- CHANGELOG.md | 1 + src/Query/Builder.php | 86 +++++++++++++++++++++++++++++++++------ tests/Models/Birthday.php | 5 +-- 3 files changed, 76 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30413ef..6bf4761 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ All notable changes to this project will be documented in this file. - Remove `Query\Builder::whereAll($column, $values)`. Use `Query\Builder::where($column, 'all', $values)` instead. [#16](https://github.com/GromNaN/laravel-mongodb-private/pull/16) by [@GromNaN](https://github.com/GromNaN). - Fix validation of unique values when the validated value is found as part of an existing value. [#21](https://github.com/GromNaN/laravel-mongodb-private/pull/21) by [@GromNaN](https://github.com/GromNaN). - Support `%` and `_` in `like` expression [#17](https://github.com/GromNaN/laravel-mongodb-private/pull/17) by [@GromNaN](https://github.com/GromNaN). +- Fix Query on `whereDate`, `whereDay`, `whereMonth`, `whereYear` to use MongoDB operators [#2376](https://github.com/jenssegers/laravel-mongodb/pull/2376) by [@Davpyu](https://github.com/Davpyu) ## [3.9.2] - 2022-09-01 diff --git a/src/Query/Builder.php b/src/Query/Builder.php index dd448ed..f330cf5 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -8,6 +8,7 @@ use Illuminate\Database\Query\Builder as BaseBuilder; use Illuminate\Database\Query\Expression; use Illuminate\Support\Arr; +use Illuminate\Support\Carbon; use Illuminate\Support\Collection; use Illuminate\Support\LazyCollection; use Illuminate\Support\Str; @@ -1191,10 +1192,45 @@ protected function compileWhereDate(array $where): array { extract($where); - $where['operator'] = $operator; - $where['value'] = $value; + $startOfDay = new UTCDateTime(Carbon::parse($value)->startOfDay()); + $endOfDay = new UTCDateTime(Carbon::parse($value)->endOfDay()); - return $this->compileWhereBasic($where); + $operator = $this->conversion[$operator]; + + return match($operator) { + '=' => [ + $column => [ + '$gte' => $startOfDay, + '$lte' => $endOfDay, + ], + ], + '$ne' => [ + $column => [ + '$gt' => $endOfDay, + '$lt' => $startOfDay, + ], + ], + '$lt' => [ + $column => [ + '$lt' => $startOfDay, + ], + ], + '$gt' => [ + $column => [ + '$gt' => $endOfDay, + ], + ], + '$lte' => [ + $column => [ + '$lte' => $endOfDay, + ], + ], + '$gte' => [ + $column => [ + '$gte' => $startOfDay, + ], + ], + }; } /** @@ -1205,10 +1241,19 @@ protected function compileWhereMonth(array $where): array { extract($where); - $where['operator'] = $operator; - $where['value'] = $value; + $operator = $operator === '=' ? '$eq' : $this->conversion[$operator]; + $value = str_starts_with($value, '0') ? intval(str_replace('0', '', $value)) : $value; - return $this->compileWhereBasic($where); + return [ + '$expr' => [ + $operator => [ + [ + '$month' => '$'.$column + ], + $value, + ], + ], + ]; } /** @@ -1219,10 +1264,19 @@ protected function compileWhereDay(array $where): array { extract($where); - $where['operator'] = $operator; - $where['value'] = $value; + $operator = $operator === '=' ? '$eq' : $this->conversion[$operator]; + $value = str_starts_with($value, '0') ? intval(str_replace('0', '', $value)) : $value; - return $this->compileWhereBasic($where); + return [ + '$expr' => [ + $operator => [ + [ + '$dayOfMonth' => '$'.$column + ], + $value, + ], + ], + ]; } /** @@ -1233,10 +1287,18 @@ protected function compileWhereYear(array $where): array { extract($where); - $where['operator'] = $operator; - $where['value'] = $value; + $operator = $operator === '=' ? '$eq' : $this->conversion[$operator]; - return $this->compileWhereBasic($where); + return [ + '$expr' => [ + $operator => [ + [ + '$year' => '$'.$column + ], + $value + ], + ], + ]; } /** diff --git a/tests/Models/Birthday.php b/tests/Models/Birthday.php index 2afca41..df8c19a 100644 --- a/tests/Models/Birthday.php +++ b/tests/Models/Birthday.php @@ -11,14 +11,11 @@ * * @property string $name * @property string $birthday - * @property string $day - * @property string $month - * @property string $year * @property string $time */ class Birthday extends Eloquent { protected $connection = 'mongodb'; protected $collection = 'birthday'; - protected $fillable = ['name', 'birthday', 'day', 'month', 'year', 'time']; + protected $fillable = ['name', 'birthday', 'time']; } From 40ee389f0ad84aca11c76eaecb1295ca6f25dc58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 21 Aug 2023 18:01:23 +0200 Subject: [PATCH 2/6] Add and fix tests --- src/Query/Builder.php | 49 +++++++---------- tests/Models/Birthday.php | 4 ++ tests/Query/BuilderTest.php | 104 ++++++++++++++++++++++++++++++++++++ tests/QueryTest.php | 51 +++++++++++++----- 4 files changed, 164 insertions(+), 44 deletions(-) diff --git a/src/Query/Builder.php b/src/Query/Builder.php index f330cf5..ed6c215 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -117,6 +117,7 @@ class Builder extends BaseBuilder * @var array */ protected $conversion = [ + '=' => 'eq', '!=' => 'ne', '<>' => 'ne', '<' => 'lt', @@ -1085,7 +1086,7 @@ protected function compileWhereBasic(array $where): array $operator = $operator === 'regex' ? '=' : 'not'; } - if (! isset($operator) || $operator == '=') { + if (! isset($operator) || $operator === '=' || $operator === 'eq') { $query = [$column => $value]; } else { $query = [$column => ['$'.$operator => $value]]; @@ -1195,39 +1196,27 @@ protected function compileWhereDate(array $where): array $startOfDay = new UTCDateTime(Carbon::parse($value)->startOfDay()); $endOfDay = new UTCDateTime(Carbon::parse($value)->endOfDay()); - $operator = $this->conversion[$operator]; - return match($operator) { - '=' => [ + 'eq', '=' => [ $column => [ '$gte' => $startOfDay, '$lte' => $endOfDay, ], ], - '$ne' => [ + 'ne' => [ $column => [ '$gt' => $endOfDay, '$lt' => $startOfDay, ], ], - '$lt' => [ - $column => [ - '$lt' => $startOfDay, - ], - ], - '$gt' => [ - $column => [ - '$gt' => $endOfDay, - ], - ], - '$lte' => [ + 'lt', 'gte' => [ $column => [ - '$lte' => $endOfDay, + '$'.$operator => $startOfDay, ], ], - '$gte' => [ + 'gt', 'lte' => [ $column => [ - '$gte' => $startOfDay, + '$'.$operator => $endOfDay, ], ], }; @@ -1241,14 +1230,13 @@ protected function compileWhereMonth(array $where): array { extract($where); - $operator = $operator === '=' ? '$eq' : $this->conversion[$operator]; - $value = str_starts_with($value, '0') ? intval(str_replace('0', '', $value)) : $value; + $value = (int) ltrim($value, '0'); return [ '$expr' => [ - $operator => [ + '$'.$operator => [ [ - '$month' => '$'.$column + '$month' => '$'.$column, ], $value, ], @@ -1264,14 +1252,13 @@ protected function compileWhereDay(array $where): array { extract($where); - $operator = $operator === '=' ? '$eq' : $this->conversion[$operator]; - $value = str_starts_with($value, '0') ? intval(str_replace('0', '', $value)) : $value; + $value = (int) ltrim($value, '0'); return [ '$expr' => [ - $operator => [ + '$'.$operator => [ [ - '$dayOfMonth' => '$'.$column + '$dayOfMonth' => '$'.$column, ], $value, ], @@ -1287,15 +1274,15 @@ protected function compileWhereYear(array $where): array { extract($where); - $operator = $operator === '=' ? '$eq' : $this->conversion[$operator]; + $value = (int) $value; return [ '$expr' => [ - $operator => [ + '$'.$operator => [ [ - '$year' => '$'.$column + '$year' => '$'.$column, ], - $value + $value, ], ], ]; diff --git a/tests/Models/Birthday.php b/tests/Models/Birthday.php index df8c19a..3accb7a 100644 --- a/tests/Models/Birthday.php +++ b/tests/Models/Birthday.php @@ -18,4 +18,8 @@ class Birthday extends Eloquent protected $connection = 'mongodb'; protected $collection = 'birthday'; protected $fillable = ['name', 'birthday', 'time']; + + protected $casts = [ + 'birthday' => 'datetime', + ]; } diff --git a/tests/Query/BuilderTest.php b/tests/Query/BuilderTest.php index f346422..cd7d2da 100644 --- a/tests/Query/BuilderTest.php +++ b/tests/Query/BuilderTest.php @@ -645,6 +645,110 @@ function (Builder $builder) { fn (Builder $builder) => $builder->where('name', 'not regex', '/^acme$/si'), ]; + yield 'where date' => [ + ['find' => [['created_at' => [ + '$gte' => new UTCDateTime(new DateTimeImmutable('2018-09-30 00:00:00.000 +00:00')), + '$lte' => new UTCDateTime(new DateTimeImmutable('2018-09-30 23:59:59.999 +00:00')), + ]], []]], + fn (Builder $builder) => $builder->whereDate('created_at', '2018-09-30'), + ]; + + yield 'where date DateTimeImmutable' => [ + ['find' => [['created_at' => [ + '$gte' => new UTCDateTime(new DateTimeImmutable('2018-09-30 00:00:00.000 +00:00')), + '$lte' => new UTCDateTime(new DateTimeImmutable('2018-09-30 23:59:59.999 +00:00')), + ]], []]], + fn (Builder $builder) => $builder->whereDate('created_at', '=', new DateTimeImmutable('2018-09-30 15:00:00 +02:00')), + ]; + + yield 'where date <' => [ + ['find' => [['created_at' => [ + '$lt' => new UTCDateTime(new DateTimeImmutable('2018-09-30 00:00:00.000 +00:00')), + ]], []]], + fn (Builder $builder) => $builder->whereDate('created_at', '<', '2018-09-30'), + ]; + + yield 'where date >=' => [ + ['find' => [['created_at' => [ + '$gte' => new UTCDateTime(new DateTimeImmutable('2018-09-30 00:00:00.000 +00:00')), + ]], []]], + fn (Builder $builder) => $builder->whereDate('created_at', '>=', '2018-09-30'), + ]; + + yield 'where date >' => [ + ['find' => [['created_at' => [ + '$gt' => new UTCDateTime(new DateTimeImmutable('2018-09-30 23:59:59.999 +00:00')), + ]], []]], + fn (Builder $builder) => $builder->whereDate('created_at', '>', '2018-09-30'), + ]; + + yield 'where date <=' => [ + ['find' => [['created_at' => [ + '$lte' => new UTCDateTime(new DateTimeImmutable('2018-09-30 23:59:59.999 +00:00')), + ]], []]], + fn (Builder $builder) => $builder->whereDate('created_at', '<=', '2018-09-30'), + ]; + + yield 'where day' => [ + ['find' => [['$expr' => [ + '$eq' => [ + ['$dayOfMonth' => '$created_at'], + 5, + ], + ]], []]], + fn (Builder $builder) => $builder->whereDay('created_at', 5), + ]; + + yield 'where day > string' => [ + ['find' => [['$expr' => [ + '$gt' => [ + ['$dayOfMonth' => '$created_at'], + 5, + ], + ]], []]], + fn (Builder $builder) => $builder->whereDay('created_at', '>', '05'), + ]; + + yield 'where month' => [ + ['find' => [['$expr' => [ + '$eq' => [ + ['$month' => '$created_at'], + 10, + ], + ]], []]], + fn (Builder $builder) => $builder->whereMonth('created_at', 10), + ]; + + yield 'where month > string' => [ + ['find' => [['$expr' => [ + '$gt' => [ + ['$month' => '$created_at'], + 5, + ], + ]], []]], + fn (Builder $builder) => $builder->whereMonth('created_at', '>', '05'), + ]; + + yield 'where year' => [ + ['find' => [['$expr' => [ + '$eq' => [ + ['$year' => '$created_at'], + 2023, + ], + ]], []]], + fn (Builder $builder) => $builder->whereYear('created_at', 2023), + ]; + + yield 'where year > string' => [ + ['find' => [['$expr' => [ + '$gt' => [ + ['$year' => '$created_at'], + 2023, + ], + ]], []]], + fn (Builder $builder) => $builder->whereYear('created_at', '>', '2023'), + ]; + /** @see DatabaseQueryBuilderTest::testBasicSelectDistinct */ yield 'distinct' => [ ['distinct' => ['foo', [], []]], diff --git a/tests/QueryTest.php b/tests/QueryTest.php index 754f204..9aca935 100644 --- a/tests/QueryTest.php +++ b/tests/QueryTest.php @@ -4,6 +4,7 @@ namespace Jenssegers\Mongodb\Tests; +use DateTimeImmutable; use Jenssegers\Mongodb\Tests\Models\Birthday; use Jenssegers\Mongodb\Tests\Models\Scoped; use Jenssegers\Mongodb\Tests\Models\User; @@ -24,12 +25,12 @@ public function setUp(): void User::create(['name' => 'Tommy Toe', 'age' => 33, 'title' => 'user']); User::create(['name' => 'Yvonne Yoe', 'age' => 35, 'title' => 'admin']); User::create(['name' => 'Error', 'age' => null, 'title' => null]); - Birthday::create(['name' => 'Mark Moe', 'birthday' => '2020-04-10', 'day' => '10', 'month' => '04', 'year' => '2020', 'time' => '10:53:11']); - Birthday::create(['name' => 'Jane Doe', 'birthday' => '2021-05-12', 'day' => '12', 'month' => '05', 'year' => '2021', 'time' => '10:53:12']); - Birthday::create(['name' => 'Harry Hoe', 'birthday' => '2021-05-11', 'day' => '11', 'month' => '05', 'year' => '2021', 'time' => '10:53:13']); - Birthday::create(['name' => 'Robert Doe', 'birthday' => '2021-05-12', 'day' => '12', 'month' => '05', 'year' => '2021', 'time' => '10:53:14']); - Birthday::create(['name' => 'Mark Moe', 'birthday' => '2021-05-12', 'day' => '12', 'month' => '05', 'year' => '2021', 'time' => '10:53:15']); - Birthday::create(['name' => 'Mark Moe', 'birthday' => '2022-05-12', 'day' => '12', 'month' => '05', 'year' => '2022', 'time' => '10:53:16']); + Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2020-04-10 10:53:11'), 'time' => '10:53:11']); + Birthday::create(['name' => 'Jane Doe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:12'), 'time' => '10:53:12']); + Birthday::create(['name' => 'Harry Hoe', 'birthday' => new DateTimeImmutable('2021-05-11 10:53:13'), 'time' => '10:53:13']); + Birthday::create(['name' => 'Robert Doe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:14'), 'time' => '10:53:14']); + Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:15'), 'time' => '10:53:15']); + Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2022-05-12 10:53:16'), 'time' => '10:53:16']); } public function tearDown(): void @@ -204,36 +205,60 @@ public function testWhereDate(): void $birthdayCount = Birthday::whereDate('birthday', '2021-05-11')->get(); $this->assertCount(1, $birthdayCount); + + $birthdayCount = Birthday::whereDate('birthday', '>', '2021-05-11')->get(); + $this->assertCount(4, $birthdayCount); + + $birthdayCount = Birthday::whereDate('birthday', '>=', '2021-05-11')->get(); + $this->assertCount(5, $birthdayCount); + + $birthdayCount = Birthday::whereDate('birthday', '<', '2021-05-11')->get(); + $this->assertCount(1, $birthdayCount); + + $birthdayCount = Birthday::whereDate('birthday', '<=', '2021-05-11')->get(); + $this->assertCount(2, $birthdayCount); } public function testWhereDay(): void { - $day = Birthday::whereDay('day', '12')->get(); + $day = Birthday::whereDay('birthday', '12')->get(); $this->assertCount(4, $day); - $day = Birthday::whereDay('day', '11')->get(); + $day = Birthday::whereDay('birthday', '11')->get(); $this->assertCount(1, $day); } public function testWhereMonth(): void { - $month = Birthday::whereMonth('month', '04')->get(); + $month = Birthday::whereMonth('birthday', '04')->get(); $this->assertCount(1, $month); - $month = Birthday::whereMonth('month', '05')->get(); + $month = Birthday::whereMonth('birthday', '05')->get(); $this->assertCount(5, $month); + + $month = Birthday::whereMonth('birthday', '>=', '5')->get(); + $this->assertCount(5, $month); + + $month = Birthday::whereMonth('birthday', '<', '10')->get(); + $this->assertCount(6, $month); + + $month = Birthday::whereMonth('birthday', '<>', '5')->get(); + $this->assertCount(1, $month); } public function testWhereYear(): void { - $year = Birthday::whereYear('year', '2021')->get(); + $year = Birthday::whereYear('birthday', '2021')->get(); $this->assertCount(4, $year); - $year = Birthday::whereYear('year', '2022')->get(); + $year = Birthday::whereYear('birthday', '2022')->get(); $this->assertCount(1, $year); - $year = Birthday::whereYear('year', '<', '2021')->get(); + $year = Birthday::whereYear('birthday', '<', '2021')->get(); $this->assertCount(1, $year); + + $year = Birthday::whereYear('birthday', '<>', '2021')->get(); + $this->assertCount(2, $year); } public function testWhereTime(): void From 9ffc4926521bf4fb6ba43f3e60e6ba03ec060c90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 21 Aug 2023 18:20:04 +0200 Subject: [PATCH 3/6] Fix whereDate --- src/Query/Builder.php | 14 +++++++++++--- tests/Query/BuilderTest.php | 8 ++++++++ tests/QueryTest.php | 12 ++++++++---- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/Query/Builder.php b/src/Query/Builder.php index ed6c215..589457e 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -1204,9 +1204,17 @@ protected function compileWhereDate(array $where): array ], ], 'ne' => [ - $column => [ - '$gt' => $endOfDay, - '$lt' => $startOfDay, + '$or' => [ + [ + $column => [ + '$lt' => $startOfDay, + ], + ], + [ + $column => [ + '$gt' => $endOfDay, + ], + ], ], ], 'lt', 'gte' => [ diff --git a/tests/Query/BuilderTest.php b/tests/Query/BuilderTest.php index cd7d2da..e8c71a4 100644 --- a/tests/Query/BuilderTest.php +++ b/tests/Query/BuilderTest.php @@ -661,6 +661,14 @@ function (Builder $builder) { fn (Builder $builder) => $builder->whereDate('created_at', '=', new DateTimeImmutable('2018-09-30 15:00:00 +02:00')), ]; + yield 'where date !=' => [ + ['find' => [['$or' => [ + ['created_at' => ['$lt' => new UTCDateTime(new DateTimeImmutable('2018-09-30 00:00:00.000 +00:00'))]], + ['created_at' => ['$gt' => new UTCDateTime(new DateTimeImmutable('2018-09-30 23:59:59.999 +00:00'))]], + ]], []]], + fn (Builder $builder) => $builder->whereDate('created_at', '!=', '2018-09-30'), + ]; + yield 'where date <' => [ ['find' => [['created_at' => [ '$lt' => new UTCDateTime(new DateTimeImmutable('2018-09-30 00:00:00.000 +00:00')), diff --git a/tests/QueryTest.php b/tests/QueryTest.php index 9aca935..889f36d 100644 --- a/tests/QueryTest.php +++ b/tests/QueryTest.php @@ -31,6 +31,7 @@ public function setUp(): void Birthday::create(['name' => 'Robert Doe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:14'), 'time' => '10:53:14']); Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:15'), 'time' => '10:53:15']); Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2022-05-12 10:53:16'), 'time' => '10:53:16']); + Birthday::create(['name' => 'Boo']); } public function tearDown(): void @@ -217,6 +218,9 @@ public function testWhereDate(): void $birthdayCount = Birthday::whereDate('birthday', '<=', '2021-05-11')->get(); $this->assertCount(2, $birthdayCount); + + $birthdayCount = Birthday::whereDate('birthday', '<>', '2021-05-11')->get(); + $this->assertCount(5, $birthdayCount); } public function testWhereDay(): void @@ -240,10 +244,10 @@ public function testWhereMonth(): void $this->assertCount(5, $month); $month = Birthday::whereMonth('birthday', '<', '10')->get(); - $this->assertCount(6, $month); + $this->assertCount(7, $month); $month = Birthday::whereMonth('birthday', '<>', '5')->get(); - $this->assertCount(1, $month); + $this->assertCount(2, $month); } public function testWhereYear(): void @@ -255,10 +259,10 @@ public function testWhereYear(): void $this->assertCount(1, $year); $year = Birthday::whereYear('birthday', '<', '2021')->get(); - $this->assertCount(1, $year); + $this->assertCount(2, $year); $year = Birthday::whereYear('birthday', '<>', '2021')->get(); - $this->assertCount(2, $year); + $this->assertCount(3, $year); } public function testWhereTime(): void From 4cc05b34163561dee282fcc1ece5b304278e4009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 21 Aug 2023 21:51:13 +0200 Subject: [PATCH 4/6] PHPORM-60 Native support for whereTime --- CHANGELOG.md | 2 +- src/Query/Builder.php | 14 ++++++++++---- tests/Query/BuilderTest.php | 20 ++++++++++++++++++++ tests/QueryTest.php | 22 ++++++++++++++-------- 4 files changed, 45 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6bf4761..e563b47 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,7 +16,7 @@ All notable changes to this project will be documented in this file. - Remove `Query\Builder::whereAll($column, $values)`. Use `Query\Builder::where($column, 'all', $values)` instead. [#16](https://github.com/GromNaN/laravel-mongodb-private/pull/16) by [@GromNaN](https://github.com/GromNaN). - Fix validation of unique values when the validated value is found as part of an existing value. [#21](https://github.com/GromNaN/laravel-mongodb-private/pull/21) by [@GromNaN](https://github.com/GromNaN). - Support `%` and `_` in `like` expression [#17](https://github.com/GromNaN/laravel-mongodb-private/pull/17) by [@GromNaN](https://github.com/GromNaN). -- Fix Query on `whereDate`, `whereDay`, `whereMonth`, `whereYear` to use MongoDB operators [#2376](https://github.com/jenssegers/laravel-mongodb/pull/2376) by [@Davpyu](https://github.com/Davpyu) +- Fix Query on `whereDate`, `whereDay`, `whereMonth`, `whereYear`, `whereTime` to use MongoDB operators [#2376](https://github.com/jenssegers/laravel-mongodb/pull/2376) by [@Davpyu](https://github.com/Davpyu) ## [3.9.2] - 2022-09-01 diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 589457e..4565747 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -1304,10 +1304,16 @@ protected function compileWhereTime(array $where): array { extract($where); - $where['operator'] = $operator; - $where['value'] = $value; - - return $this->compileWhereBasic($where); + return [ + '$expr' => [ + '$'.$operator => [ + [ + '$dateToString' => ['date' => '$'.$column, 'format' => '%H:%M:%S'], + ], + $value, + ], + ], + ]; } /** diff --git a/tests/Query/BuilderTest.php b/tests/Query/BuilderTest.php index e8c71a4..9a6ccf0 100644 --- a/tests/Query/BuilderTest.php +++ b/tests/Query/BuilderTest.php @@ -757,6 +757,26 @@ function (Builder $builder) { fn (Builder $builder) => $builder->whereYear('created_at', '>', '2023'), ]; + yield 'where time' => [ + ['find' => [['$expr' => [ + '$eq' => [ + ['$dateToString' => ['date' => '$created_at', 'format' => '%H:%M:%S']], + '10:11:12', + ], + ]], []]], + fn (Builder $builder) => $builder->whereTime('created_at', '10:11:12'), + ]; + + yield 'where time >' => [ + ['find' => [['$expr' => [ + '$gt' => [ + ['$dateToString' => ['date' => '$created_at', 'format' => '%H:%M:%S']], + '10:11:12', + ], + ]], []]], + fn (Builder $builder) => $builder->whereTime('created_at', '>', '10:11:12'), + ]; + /** @see DatabaseQueryBuilderTest::testBasicSelectDistinct */ yield 'distinct' => [ ['distinct' => ['foo', [], []]], diff --git a/tests/QueryTest.php b/tests/QueryTest.php index 889f36d..0d3fef1 100644 --- a/tests/QueryTest.php +++ b/tests/QueryTest.php @@ -25,12 +25,12 @@ public function setUp(): void User::create(['name' => 'Tommy Toe', 'age' => 33, 'title' => 'user']); User::create(['name' => 'Yvonne Yoe', 'age' => 35, 'title' => 'admin']); User::create(['name' => 'Error', 'age' => null, 'title' => null]); - Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2020-04-10 10:53:11'), 'time' => '10:53:11']); - Birthday::create(['name' => 'Jane Doe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:12'), 'time' => '10:53:12']); - Birthday::create(['name' => 'Harry Hoe', 'birthday' => new DateTimeImmutable('2021-05-11 10:53:13'), 'time' => '10:53:13']); - Birthday::create(['name' => 'Robert Doe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:14'), 'time' => '10:53:14']); - Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:15'), 'time' => '10:53:15']); - Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2022-05-12 10:53:16'), 'time' => '10:53:16']); + Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2020-04-10 10:53:11')]); + Birthday::create(['name' => 'Jane Doe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:12')]); + Birthday::create(['name' => 'Harry Hoe', 'birthday' => new DateTimeImmutable('2021-05-11 10:53:13')]); + Birthday::create(['name' => 'Robert Doe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:14')]); + Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2021-05-12 10:53:15')]); + Birthday::create(['name' => 'Mark Moe', 'birthday' => new DateTimeImmutable('2022-05-12 10:53:16')]); Birthday::create(['name' => 'Boo']); } @@ -267,11 +267,17 @@ public function testWhereYear(): void public function testWhereTime(): void { - $time = Birthday::whereTime('time', '10:53:11')->get(); + $time = Birthday::whereTime('birthday', '10:53:11')->get(); $this->assertCount(1, $time); - $time = Birthday::whereTime('time', '>=', '10:53:14')->get(); + $time = Birthday::whereTime('birthday', '>=', '10:53:14')->get(); $this->assertCount(3, $time); + + $time = Birthday::whereTime('birthday', '!=', '10:53:14')->get(); + $this->assertCount(6, $time); + + $time = Birthday::whereTime('birthday', '<', '10:53:12')->get(); + $this->assertCount(2, $time); } public function testOrder(): void From 5695e386a79ffa9ea867dd1f77e0cf2d3ea51dd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Mon, 21 Aug 2023 23:41:44 +0200 Subject: [PATCH 5/6] Remove magic extract to use explicit array access to options --- src/Query/Builder.php | 60 ++++++++++++++++--------------------------- 1 file changed, 22 insertions(+), 38 deletions(-) diff --git a/src/Query/Builder.php b/src/Query/Builder.php index 4565747..9fc2b21 100644 --- a/src/Query/Builder.php +++ b/src/Query/Builder.php @@ -1191,14 +1191,12 @@ protected function compileWhereBetween(array $where): array */ protected function compileWhereDate(array $where): array { - extract($where); - - $startOfDay = new UTCDateTime(Carbon::parse($value)->startOfDay()); - $endOfDay = new UTCDateTime(Carbon::parse($value)->endOfDay()); + $startOfDay = new UTCDateTime(Carbon::parse($where['value'])->startOfDay()); + $endOfDay = new UTCDateTime(Carbon::parse($where['value'])->endOfDay()); - return match($operator) { + return match($where['operator']) { 'eq', '=' => [ - $column => [ + $where['column'] => [ '$gte' => $startOfDay, '$lte' => $endOfDay, ], @@ -1206,25 +1204,25 @@ protected function compileWhereDate(array $where): array 'ne' => [ '$or' => [ [ - $column => [ + $where['column'] => [ '$lt' => $startOfDay, ], ], [ - $column => [ + $where['column'] => [ '$gt' => $endOfDay, ], ], ], ], 'lt', 'gte' => [ - $column => [ - '$'.$operator => $startOfDay, + $where['column'] => [ + '$'.$where['operator'] => $startOfDay, ], ], 'gt', 'lte' => [ - $column => [ - '$'.$operator => $endOfDay, + $where['column'] => [ + '$'.$where['operator'] => $endOfDay, ], ], }; @@ -1236,17 +1234,13 @@ protected function compileWhereDate(array $where): array */ protected function compileWhereMonth(array $where): array { - extract($where); - - $value = (int) ltrim($value, '0'); - return [ '$expr' => [ - '$'.$operator => [ + '$'.$where['operator'] => [ [ - '$month' => '$'.$column, + '$month' => '$'.$where['column'], ], - $value, + (int) $where['value'], ], ], ]; @@ -1258,17 +1252,13 @@ protected function compileWhereMonth(array $where): array */ protected function compileWhereDay(array $where): array { - extract($where); - - $value = (int) ltrim($value, '0'); - return [ '$expr' => [ - '$'.$operator => [ + '$'.$where['operator'] => [ [ - '$dayOfMonth' => '$'.$column, + '$dayOfMonth' => '$'.$where['column'], ], - $value, + (int) $where['value'], ], ], ]; @@ -1280,17 +1270,13 @@ protected function compileWhereDay(array $where): array */ protected function compileWhereYear(array $where): array { - extract($where); - - $value = (int) $value; - return [ '$expr' => [ - '$'.$operator => [ + '$'.$where['operator'] => [ [ - '$year' => '$'.$column, + '$year' => '$'.$where['column'], ], - $value, + (int) $where['value'], ], ], ]; @@ -1302,15 +1288,13 @@ protected function compileWhereYear(array $where): array */ protected function compileWhereTime(array $where): array { - extract($where); - return [ '$expr' => [ - '$'.$operator => [ + '$'.$where['operator'] => [ [ - '$dateToString' => ['date' => '$'.$column, 'format' => '%H:%M:%S'], + '$dateToString' => ['date' => '$'.$where['column'], 'format' => '%H:%M:%S'], ], - $value, + $where['value'], ], ], ]; From 0e018b1da6e3964891e4726281a1e0c40374b587 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 22 Aug 2023 00:03:41 +0200 Subject: [PATCH 6/6] Update tests/Models/Birthday.php --- tests/Models/Birthday.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Models/Birthday.php b/tests/Models/Birthday.php index 3accb7a..712d18d 100644 --- a/tests/Models/Birthday.php +++ b/tests/Models/Birthday.php @@ -17,7 +17,7 @@ class Birthday extends Eloquent { protected $connection = 'mongodb'; protected $collection = 'birthday'; - protected $fillable = ['name', 'birthday', 'time']; + protected $fillable = ['name', 'birthday']; protected $casts = [ 'birthday' => 'datetime',