From bc19a5897ba707227692ce6761b2348f940657e7 Mon Sep 17 00:00:00 2001 From: Einar Hansen <49709354+einar-hansen@users.noreply.github.com> Date: Mon, 5 Aug 2024 06:58:25 +0200 Subject: [PATCH 1/7] Update docblock to accept DB::raw() and set operator to mixed --- src/Illuminate/Database/Query/Builder.php | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 20b18b9025cb..7dde9d31b1b4 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -2238,7 +2238,7 @@ public function orWhereFullText($columns, $value, array $options = []) /** * Add a "where" clause to the query for multiple columns with "and" conditions between them. * - * @param string[] $columns + * @param \Illuminate\Contracts\Database\Query\Expression[]|string[] $columns * @param mixed $operator * @param mixed $value * @param string $boolean @@ -2262,8 +2262,8 @@ public function whereAll($columns, $operator = null, $value = null, $boolean = ' /** * Add an "or where" clause to the query for multiple columns with "and" conditions between them. * - * @param string[] $columns - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression[]|string[] $columns + * @param mixed $operator * @param mixed $value * @return $this */ @@ -2275,8 +2275,8 @@ public function orWhereAll($columns, $operator = null, $value = null) /** * Add a "where" clause to the query for multiple columns with "or" conditions between them. * - * @param string[] $columns - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression[]|string[] $columns + * @param mixed $operator * @param mixed $value * @param string $boolean * @return $this @@ -2299,8 +2299,8 @@ public function whereAny($columns, $operator = null, $value = null, $boolean = ' /** * Add an "or where" clause to the query for multiple columns with "or" conditions between them. * - * @param string[] $columns - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression[]|string[] $columns + * @param mixed $operator * @param mixed $value * @return $this */ @@ -2312,8 +2312,8 @@ public function orWhereAny($columns, $operator = null, $value = null) /** * Add a "where not" clause to the query for multiple columns where none of the conditions should be true. * - * @param string[] $columns - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression[]|string[] $columns + * @param mixed $operator * @param mixed $value * @param string $boolean * @return $this @@ -2326,8 +2326,8 @@ public function whereNone($columns, $operator = null, $value = null, $boolean = /** * Add an "or where not" clause to the query for multiple columns where none of the conditions should be true. * - * @param string[] $columns - * @param string $operator + * @param \Illuminate\Contracts\Database\Query\Expression[]|string[] $columns + * @param mixed $operator * @param mixed $value * @return $this */ From 19b997e145b6b736a943fdc927e3b6c2538de7b0 Mon Sep 17 00:00:00 2001 From: Einar Hansen <49709354+einar-hansen@users.noreply.github.com> Date: Mon, 5 Aug 2024 07:25:22 +0200 Subject: [PATCH 2/7] Add whereNotAny and orWhereNotAny methods to the query builder --- src/Illuminate/Database/Query/Builder.php | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index 7dde9d31b1b4..a3ab8accb9de 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -2309,6 +2309,33 @@ public function orWhereAny($columns, $operator = null, $value = null) return $this->whereAny($columns, $operator, $value, 'or'); } + /** + * Add a "where not" clause to the query for multiple columns with "or" conditions between them. + * + * @param \Illuminate\Contracts\Database\Query\Expression[]|string[] $columns + * @param mixed $operator + * @param mixed $value + * @param string $boolean + * @return $this + */ + public function whereNotAny($columns, $operator = null, $value = null, $boolean = 'and') + { + return $this->whereAny($columns, $operator, $value, $boolean.' not'); + } + + /** + * Add an "or where not" clause to the query for multiple columns with "or" conditions between them. + * + * @param \Illuminate\Contracts\Database\Query\Expression[]|string[] $columns + * @param mixed $operator + * @param mixed $value + * @return $this + */ + public function orWhereNotAny($columns, $operator = null, $value = null) + { + return $this->whereNotAny($columns, $operator, $value, 'or'); + } + /** * Add a "where not" clause to the query for multiple columns where none of the conditions should be true. * From 78bcc28415c2ed6ddfb5604e533c817f8cbaa91a Mon Sep 17 00:00:00 2001 From: Einar Hansen <49709354+einar-hansen@users.noreply.github.com> Date: Mon, 5 Aug 2024 07:26:35 +0200 Subject: [PATCH 3/7] Make whereNone deprecated and an alias for whereNotAny --- src/Illuminate/Database/Query/Builder.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Illuminate/Database/Query/Builder.php b/src/Illuminate/Database/Query/Builder.php index a3ab8accb9de..1a55c509caca 100755 --- a/src/Illuminate/Database/Query/Builder.php +++ b/src/Illuminate/Database/Query/Builder.php @@ -2339,6 +2339,8 @@ public function orWhereNotAny($columns, $operator = null, $value = null) /** * Add a "where not" clause to the query for multiple columns where none of the conditions should be true. * + * @deprecated Will be removed in a future Laravel version. Use whereNotAny instead. + * * @param \Illuminate\Contracts\Database\Query\Expression[]|string[] $columns * @param mixed $operator * @param mixed $value @@ -2347,12 +2349,14 @@ public function orWhereNotAny($columns, $operator = null, $value = null) */ public function whereNone($columns, $operator = null, $value = null, $boolean = 'and') { - return $this->whereAny($columns, $operator, $value, $boolean.' not'); + return $this->whereNotAny($columns, $operator, $value, $boolean); } /** * Add an "or where not" clause to the query for multiple columns where none of the conditions should be true. * + * @deprecated Will be removed in a future Laravel version. Use orWhereNotAny instead. + * * @param \Illuminate\Contracts\Database\Query\Expression[]|string[] $columns * @param mixed $operator * @param mixed $value @@ -2360,7 +2364,7 @@ public function whereNone($columns, $operator = null, $value = null, $boolean = */ public function orWhereNone($columns, $operator = null, $value = null) { - return $this->whereNone($columns, $operator, $value, 'or'); + return $this->orWhereNotAny($columns, $operator, $value); } /** From dd11132917963ea4d0a000f95d312fb0df896442 Mon Sep 17 00:00:00 2001 From: Einar Hansen <49709354+einar-hansen@users.noreply.github.com> Date: Mon, 5 Aug 2024 07:40:48 +0200 Subject: [PATCH 4/7] Add tests for the whereNotAny methods --- tests/Database/DatabaseQueryBuilderTest.php | 46 +++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index aa32a552566f..e68414373bd1 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -1376,6 +1376,52 @@ public function testOrWhereAny() $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); } + public function testWhereNotAny() + { + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNotAny(['last_name', 'email'], 'like', '%Otwell%'); + $this->assertSame('select * from "users" where not ("last_name" like ? or "email" like ?)', $builder->toSql()); + $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->whereNotAny(['email_verified_at', 'deleted_at'], null); + $this->assertSame('select * from "users" where "first_name" like ? and not ("email_verified_at" is null or "deleted_at" is null)', $builder->toSql()); + $this->assertEquals(['%Taylor%'], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->whereNotAny(['last_name', 'email'], 'like', '%Otwell%'); + $this->assertSame('select * from "users" where "first_name" like ? and not ("last_name" like ? or "email" like ?)', $builder->toSql()); + $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereNotAny(['email_verified_at', 'deleted_at'], null); + $this->assertSame('select * from "users" where not ("email_verified_at" is null or "deleted_at" is null)', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); + } + + public function testOrWhereNotAny() + { + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereNotAny(['last_name', 'email'], 'like', '%Otwell%'); + $this->assertSame('select * from "users" where "first_name" like ? or not ("last_name" like ? or "email" like ?)', $builder->toSql()); + $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereNotAny(['last_name', 'email'], '%Otwell%'); + $this->assertSame('select * from "users" where "first_name" like ? or not ("last_name" = ? or "email" = ?)', $builder->toSql()); + $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereNotAny(['last_name', 'deleted_at'], null); + $this->assertSame('select * from "users" where "first_name" like ? or not ("last_name" is null or "deleted_at" is null)', $builder->toSql()); + $this->assertEquals(['%Taylor%'], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->whereNotAny(['last_name', 'email'], 'like', '%Otwell%', 'or'); + $this->assertSame('select * from "users" where "first_name" like ? or not ("last_name" like ? or "email" like ?)', $builder->toSql()); + $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); + } + public function testWhereNone() { $builder = $this->getBuilder(); From 721aba35f5ed96e0353db494e28ef397191fe408 Mon Sep 17 00:00:00 2001 From: Einar Hansen <49709354+einar-hansen@users.noreply.github.com> Date: Mon, 5 Aug 2024 07:41:31 +0200 Subject: [PATCH 5/7] Test where(All|Any|NotAny) for is null --- tests/Database/DatabaseQueryBuilderTest.php | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index e68414373bd1..a48dc2c9082d 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -1325,6 +1325,11 @@ public function testWhereAll() $builder->select('*')->from('users')->whereAll(['last_name', 'email'], 'not like', '%Otwell%'); $this->assertSame('select * from "users" where ("last_name" not like ? and "email" not like ?)', $builder->toSql()); $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereAll(['email_verified_at', 'deleted_at'], null); + $this->assertSame('select * from "users" where ("email_verified_at" is null and "deleted_at" is null)', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); } public function testOrWhereAll() @@ -1343,6 +1348,11 @@ public function testOrWhereAll() $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAll(['last_name', 'email'], '%Otwell%'); $this->assertSame('select * from "users" where "first_name" like ? or ("last_name" = ? and "email" = ?)', $builder->toSql()); $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereAll(['email_verified_at', 'deleted_at'], null); + $this->assertSame('select * from "users" where ("email_verified_at" is null and "deleted_at" is null)', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); } public function testWhereAny() @@ -1356,6 +1366,11 @@ public function testWhereAny() $builder->select('*')->from('users')->whereAny(['last_name', 'email'], '%Otwell%'); $this->assertSame('select * from "users" where ("last_name" = ? or "email" = ?)', $builder->toSql()); $this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings()); + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->whereAny(['email_verified_at', 'deleted_at'], null); + $this->assertSame('select * from "users" where ("email_verified_at" is null or "deleted_at" is null)', $builder->toSql()); + $this->assertEquals([], $builder->getBindings()); } public function testOrWhereAny() @@ -1374,6 +1389,12 @@ public function testOrWhereAny() $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAny(['last_name', 'email'], '%Otwell%'); $this->assertSame('select * from "users" where "first_name" like ? or ("last_name" = ? or "email" = ?)', $builder->toSql()); $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); + + + $builder = $this->getBuilder(); + $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAny(['email_verified_at', 'deleted_at'], null); + $this->assertSame('select * from "users" where "first_name" like ? or ("email_verified_at" is null or "deleted_at" is null)', $builder->toSql()); + $this->assertEquals(['%Taylor%'], $builder->getBindings()); } public function testWhereNotAny() From 8d0a3f35b4d51e447068e43df8c3edc84b9b0483 Mon Sep 17 00:00:00 2001 From: Einar Hansen <49709354+einar-hansen@users.noreply.github.com> Date: Mon, 5 Aug 2024 07:42:13 +0200 Subject: [PATCH 6/7] Remove some of the tests for the now deprecated whereNone methods --- tests/Database/DatabaseQueryBuilderTest.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index a48dc2c9082d..50032cebeeef 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -1454,11 +1454,6 @@ public function testWhereNone() $builder->select('*')->from('users')->whereNone(['last_name', 'email'], 'Otwell'); $this->assertSame('select * from "users" where not ("last_name" = ? or "email" = ?)', $builder->toSql()); $this->assertEquals(['Otwell', 'Otwell'], $builder->getBindings()); - - $builder = $this->getBuilder(); - $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->whereNone(['last_name', 'email'], 'like', '%Otwell%'); - $this->assertSame('select * from "users" where "first_name" like ? and not ("last_name" like ? or "email" like ?)', $builder->toSql()); - $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); } public function testOrWhereNone() @@ -1472,11 +1467,6 @@ public function testOrWhereNone() $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->whereNone(['last_name', 'email'], 'like', '%Otwell%', 'or'); $this->assertSame('select * from "users" where "first_name" like ? or not ("last_name" like ? or "email" like ?)', $builder->toSql()); $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); - - $builder = $this->getBuilder(); - $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereNone(['last_name', 'email'], '%Otwell%'); - $this->assertSame('select * from "users" where "first_name" like ? or not ("last_name" = ? or "email" = ?)', $builder->toSql()); - $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); } public function testUnions() From 0d8c3c3f3c219dcd694ad2f0308a35dcbec7e2cb Mon Sep 17 00:00:00 2001 From: Einar Hansen <49709354+einar-hansen@users.noreply.github.com> Date: Mon, 5 Aug 2024 09:17:41 +0200 Subject: [PATCH 7/7] Formatting --- tests/Database/DatabaseQueryBuilderTest.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/Database/DatabaseQueryBuilderTest.php b/tests/Database/DatabaseQueryBuilderTest.php index 50032cebeeef..1fc80d496dda 100755 --- a/tests/Database/DatabaseQueryBuilderTest.php +++ b/tests/Database/DatabaseQueryBuilderTest.php @@ -1390,7 +1390,6 @@ public function testOrWhereAny() $this->assertSame('select * from "users" where "first_name" like ? or ("last_name" = ? or "email" = ?)', $builder->toSql()); $this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings()); - $builder = $this->getBuilder(); $builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAny(['email_verified_at', 'deleted_at'], null); $this->assertSame('select * from "users" where "first_name" like ? or ("email_verified_at" is null or "deleted_at" is null)', $builder->toSql());