Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add whereLike clause to query builder #52147

Merged
65 changes: 65 additions & 0 deletions src/Illuminate/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -1121,6 +1121,71 @@ public function orWhereRaw($sql, $bindings = [])
return $this->whereRaw($sql, $bindings, 'or');
}

/**
* Add a "where like" clause to the query.
*
* @param string $column
* @param string $value
* @param bool $caseSensitive
* @param string $boolean
* @param bool $not
* @return $this
*/
public function whereLike($column, $value, $caseSensitive = false, $boolean = 'and', $not = false)
{
$type = 'Like';

$this->wheres[] = compact('type', 'column', 'value', 'caseSensitive', 'boolean', 'not');

if (method_exists($this->grammar, 'prepareWhereLikeBinding')) {
$value = $this->grammar->prepareWhereLikeBinding($value, $caseSensitive);
}

$this->addBinding($value);

return $this;
}

/**
* Add an "or where like" clause to the query.
*
* @param string $column
* @param string $value
* @param bool $caseSensitive
* @return $this
*/
public function orWhereLike($column, $value, $caseSensitive = false)
{
return $this->whereLike($column, $value, $caseSensitive, 'or', false);
}

/**
* Add a "where not like" clause to the query.
*
* @param string $column
* @param string $value
* @param bool $caseSensitive
* @param string $boolean
* @return $this
*/
public function whereNotLike($column, $value, $caseSensitive = false, $boolean = 'and')
{
return $this->whereLike($column, $value, $caseSensitive, $boolean, true);
}

/**
* Add an "or where not like" clause to the query.
*
* @param string $columns
* @param string $value
* @param bool $caseSensitive
* @return $this
*/
public function orWhereNotLike($column, $value, $caseSensitive = false)
{
return $this->whereNotLike($column, $value, $caseSensitive, 'or');
}

/**
* Add a "where in" clause to the query.
*
Expand Down
18 changes: 18 additions & 0 deletions src/Illuminate/Database/Query/Grammars/Grammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,24 @@ protected function whereBitwise(Builder $query, $where)
return $this->whereBasic($query, $where);
}

/**
* Compile a "where like" clause.
*
* @param \Illuminate\Database\Query\Builder $query
* @param array $where
* @return string
*/
protected function whereLike(Builder $query, $where)
{
if ($where['caseSensitive']) {
throw new RuntimeException('This database engine does not support case sensitive like operations.');
}

$where['operator'] = $where['not'] ? 'not like' : 'like';

return $this->whereBasic($query, $where);
}

/**
* Compile a "where in" clause.
*
Expand Down
16 changes: 16 additions & 0 deletions src/Illuminate/Database/Query/Grammars/MySqlGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,22 @@ class MySqlGrammar extends Grammar
*/
protected $operators = ['sounds like'];

/**
* Compile a "where like" clause.
*
* @param \Illuminate\Database\Query\Builder $query
* @param array $where
* @return string
*/
protected function whereLike(Builder $query, $where)
{
$where['operator'] = $where['not'] ? 'not ' : '';

$where['operator'] .= $where['caseSensitive'] ? 'like binary' : 'like';

return $this->whereBasic($query, $where);
}

/**
* Add a "where null" clause to the query.
*
Expand Down
16 changes: 16 additions & 0 deletions src/Illuminate/Database/Query/Grammars/PostgresGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,22 @@ protected function whereBitwise(Builder $query, $where)
return '('.$this->wrap($where['column']).' '.$operator.' '.$value.')::bool';
}

/**
* Compile a "where like" clause.
*
* @param \Illuminate\Database\Query\Builder $query
* @param array $where
* @return string
*/
protected function whereLike(Builder $query, $where)
{
$where['operator'] = $where['not'] ? 'not ' : '';

$where['operator'] .= $where['caseSensitive'] ? 'like' : 'ilike';

return $this->whereBasic($query, $where);
}

/**
* Compile a "where date" clause.
*
Expand Down
33 changes: 33 additions & 0 deletions src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,39 @@ protected function wrapUnion($sql)
return 'select * from ('.$sql.')';
}

/**
* Compile a "where like" clause.
*
* @param \Illuminate\Database\Query\Builder $query
* @param array $where
* @return string
*/
protected function whereLike(Builder $query, $where)
{
if ($where['caseSensitive'] == false) {
return parent::whereLike($query, $where);
}
$where['operator'] = $where['not'] ? 'not glob' : 'glob';

return $this->whereBasic($query, $where);
}

/**
* Convert a LIKE pattern to a GLOB pattern using simple string replacement.
*
* @param string $value
* @param bool $caseSensitive
* @return string
*/
public function prepareWhereLikeBinding($value, $caseSensitive)
{
return $caseSensitive === false ? $value : str_replace(
['*', '?', '%', '_'],
['[*]', '[?]', '*', '?'],
$value
);
}

/**
* Compile a "where date" clause.
*
Expand Down
122 changes: 122 additions & 0 deletions tests/Database/DatabaseQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,128 @@ public function testWhereLikePostgres()
$this->assertEquals([0 => '1'], $builder->getBindings());
}

public function testWhereLikeClausePostgres()
{
$builder = $this->getPostgresBuilder();
$builder->select('*')->from('users')->whereLike('id', '1');
$this->assertSame('select * from "users" where "id"::text ilike ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getPostgresBuilder();
$builder->select('*')->from('users')->whereLike('id', '1', false);
$this->assertSame('select * from "users" where "id"::text ilike ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getPostgresBuilder();
$builder->select('*')->from('users')->whereLike('id', '1', true);
$this->assertSame('select * from "users" where "id"::text like ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getPostgresBuilder();
$builder->select('*')->from('users')->whereNotLike('id', '1');
$this->assertSame('select * from "users" where "id"::text not ilike ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getPostgresBuilder();
$builder->select('*')->from('users')->whereNotLike('id', '1', false);
$this->assertSame('select * from "users" where "id"::text not ilike ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getPostgresBuilder();
$builder->select('*')->from('users')->whereNotLike('id', '1', true);
$this->assertSame('select * from "users" where "id"::text not like ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());
}

public function testWhereLikeClauseMysql()
{
$builder = $this->getMySqlBuilder();
$builder->select('*')->from('users')->whereLike('id', '1');
$this->assertSame('select * from `users` where `id` like ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getMySqlBuilder();
$builder->select('*')->from('users')->whereLike('id', '1', false);
$this->assertSame('select * from `users` where `id` like ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getMySqlBuilder();
$builder->select('*')->from('users')->whereLike('id', '1', true);
$this->assertSame('select * from `users` where `id` like binary ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getMySqlBuilder();
$builder->select('*')->from('users')->whereNotLike('id', '1');
$this->assertSame('select * from `users` where `id` not like ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getMySqlBuilder();
$builder->select('*')->from('users')->whereNotLike('id', '1', false);
$this->assertSame('select * from `users` where `id` not like ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getMySqlBuilder();
$builder->select('*')->from('users')->whereNotLike('id', '1', true);
$this->assertSame('select * from `users` where `id` not like binary ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());
}

public function testWhereLikeClauseSqlite()
{
$builder = $this->getSQLiteBuilder();
$builder->select('*')->from('users')->whereLike('id', '1');
$this->assertSame('select * from "users" where "id" like ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getSQLiteBuilder();
$builder->select('*')->from('users')->whereLike('id', '1', true);
$this->assertSame('select * from "users" where "id" glob ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getSQLiteBuilder();
$builder->select('*')->from('users')->whereLike('description', 'Hell* _orld?%', true);
$this->assertSame('select * from "users" where "description" glob ?', $builder->toSql());
$this->assertEquals([0 => 'Hell[*] ?orld[?]*'], $builder->getBindings());

$builder = $this->getSQLiteBuilder();
$builder->select('*')->from('users')->whereNotLike('id', '1');
$this->assertSame('select * from "users" where "id" not like ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getSQLiteBuilder();
$builder->select('*')->from('users')->whereNotLike('description', 'Hell* _orld?%', true);
$this->assertSame('select * from "users" where "description" not glob ?', $builder->toSql());
$this->assertEquals([0 => 'Hell[*] ?orld[?]*'], $builder->getBindings());

$builder = $this->getSQLiteBuilder();
$builder->select('*')->from('users')->whereLike('name', 'John%', true)->whereNotLike('name', '%Doe%', true);
$this->assertSame('select * from "users" where "name" glob ? and "name" not glob ?', $builder->toSql());
$this->assertEquals([0 => 'John*', 1 => '*Doe*'], $builder->getBindings());

$builder = $this->getSQLiteBuilder();
$builder->select('*')->from('users')->whereLike('name', 'John%')->orWhereLike('name', 'Jane%', true);
$this->assertSame('select * from "users" where "name" like ? or "name" glob ?', $builder->toSql());
$this->assertEquals([0 => 'John%', 1 => 'Jane*'], $builder->getBindings());
}

public function testWhereLikeClauseSqlServer()
{
$builder = $this->getSqlServerBuilder();
$builder->select('*')->from('users')->whereLike('id', '1');
$this->assertSame('select * from [users] where [id] like ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());

$builder = $this->getSqlServerBuilder();
$builder->select('*')->from('users')->whereLike('id', '1')->orWhereLike('id', '2');
$this->assertSame('select * from [users] where [id] like ? or [id] like ?', $builder->toSql());
$this->assertEquals([0 => '1', 1 => '2'], $builder->getBindings());

$builder = $this->getSqlServerBuilder();
$builder->select('*')->from('users')->whereNotLike('id', '1');
$this->assertSame('select * from [users] where [id] not like ?', $builder->toSql());
$this->assertEquals([0 => '1'], $builder->getBindings());
}

public function testWhereDateSqlite()
{
$builder = $this->getSQLiteBuilder();
Expand Down
Loading
Loading