Skip to content

Commit

Permalink
[10.x] Add whereAll and whereAny methods to the query builder (#5…
Browse files Browse the repository at this point in the history
…0344)

* Add "whereMultiple" method to the Query Builder

* Add a test for the "whereMultiple" method

* Add a missing argument to 'assertSame' in the test

* Add new checks to test the method with different arguments

* Fix preparing of columnsBoolean and operator arguments

* Convert operators in the test to lowercase

* Trigger tests

* Fix formatting (StyleCI)

* Split 'whereMultiple' method to whereAll and whereAny

* Add tests for orWhereAll and orWhereAny methods

* Remove flatting value from 'whereMultiple' method

* Remove 'whereMultiple' method

* formatting

---------

Co-authored-by: Taylor Otwell <[email protected]>
  • Loading branch information
musiermoore and taylorotwell authored Mar 4, 2024
1 parent d7235b3 commit 5050195
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 0 deletions.
74 changes: 74 additions & 0 deletions src/Illuminate/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -2095,6 +2095,80 @@ public function orWhereFullText($columns, $value, array $options = [])
return $this->whereFulltext($columns, $value, $options, 'or');
}

/**
* Add a "where" clause to the query for multiple columns with "and" conditions between them.
*
* @param string[] $columns
* @param mixed $operator
* @param mixed $value
* @param string $boolean
* @return $this
*/
public function whereAll($columns, $operator = null, $value = null, $boolean = 'and')
{
[$value, $operator] = $this->prepareValueAndOperator(
$value, $operator, func_num_args() === 2
);

$this->whereNested(function ($query) use ($columns, $operator, $value) {
foreach ($columns as $column) {
$query->where($column, $operator, $value, 'and');
}
}, $boolean);

return $this;
}

/**
* Add an "or where" clause to the query for multiple columns with "and" conditions between them.
*
* @param string[] $columns
* @param string $operator
* @param mixed $value
* @return $this
*/
public function orWhereAll($columns, $operator = null, $value = null)
{
return $this->whereAll($columns, $operator, $value, 'or');
}

/**
* Add an "where" clause to the query for multiple columns with "or" conditions between them.
*
* @param string[] $columns
* @param string $operator
* @param mixed $value
* @param string $boolean
* @return $this
*/
public function whereAny($columns, $operator = null, $value = null, $boolean = 'and')
{
[$value, $operator] = $this->prepareValueAndOperator(
$value, $operator, func_num_args() === 2
);

$this->whereNested(function ($query) use ($columns, $operator, $value) {
foreach ($columns as $column) {
$query->where($column, $operator, $value, 'or');
}
}, $boolean);

return $this;
}

/**
* Add an "or where" clause to the query for multiple columns with "or" conditions between them.
*
* @param string[] $columns
* @param string $operator
* @param mixed $value
* @return $this
*/
public function orWhereAny($columns, $operator = null, $value = null)
{
return $this->whereAny($columns, $operator, $value, 'or');
}

/**
* Add a "group by" clause to the query.
*
Expand Down
62 changes: 62 additions & 0 deletions tests/Database/DatabaseQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,68 @@ public function testWhereFulltextPostgres()
$this->assertEquals(['Car Plane'], $builder->getBindings());
}

public function testWhereAll()
{
$builder = $this->getBuilder();
$builder->select('*')->from('users')->whereAll(['last_name', 'email'], '%Otwell%');
$this->assertSame('select * from "users" where ("last_name" = ? and "email" = ?)', $builder->toSql());
$this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings());

$builder = $this->getBuilder();
$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());
}

public function testOrWhereAll()
{
$builder = $this->getBuilder();
$builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAll(['last_name', 'email'], 'like', '%Otwell%');
$this->assertSame('select * from "users" where "first_name" like ? or ("last_name" like ? and "email" like ?)', $builder->toSql());
$this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());

$builder = $this->getBuilder();
$builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->whereAll(['last_name', 'email'], 'like', '%Otwell%', 'or');
$this->assertSame('select * from "users" where "first_name" like ? or ("last_name" like ? and "email" like ?)', $builder->toSql());
$this->assertEquals(['%Taylor%', '%Otwell%', '%Otwell%'], $builder->getBindings());

$builder = $this->getBuilder();
$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());
}

public function testWhereAny()
{
$builder = $this->getBuilder();
$builder->select('*')->from('users')->whereAny(['last_name', 'email'], 'like', '%Otwell%');
$this->assertSame('select * from "users" where ("last_name" like ? or "email" like ?)', $builder->toSql());
$this->assertEquals(['%Otwell%', '%Otwell%'], $builder->getBindings());

$builder = $this->getBuilder();
$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());
}

public function testOrWhereAny()
{
$builder = $this->getBuilder();
$builder->select('*')->from('users')->where('first_name', 'like', '%Taylor%')->orWhereAny(['last_name', 'email'], 'like', '%Otwell%');
$this->assertSame('select * from "users" where "first_name" like ? or ("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%')->whereAny(['last_name', 'email'], 'like', '%Otwell%', 'or');
$this->assertSame('select * from "users" where "first_name" like ? or ("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%')->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());
}

public function testUnions()
{
$builder = $this->getBuilder();
Expand Down

0 comments on commit 5050195

Please sign in to comment.