Skip to content

Commit

Permalink
Add Builder::whereJsonNotContains()
Browse files Browse the repository at this point in the history
  • Loading branch information
staudenmeir committed May 29, 2018
1 parent 5337149 commit 55a30f9
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 3 deletions.
30 changes: 28 additions & 2 deletions src/Illuminate/Database/Query/Builder.php
Original file line number Diff line number Diff line change
Expand Up @@ -1439,13 +1439,14 @@ public function orWhereRowValues($columns, $operator, $values)
* @param string $column
* @param mixed $value
* @param string $boolean
* @param bool $not
* @return $this
*/
public function whereJsonContains($column, $value, $boolean = 'and')
public function whereJsonContains($column, $value, $boolean = 'and', $not = false)
{
$type = 'JsonContains';

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

if (! $value instanceof Expression) {
$this->addBinding(json_encode($value));
Expand All @@ -1466,6 +1467,31 @@ public function orWhereJsonContains($column, $value)
return $this->whereJsonContains($column, $value, 'or');
}

/**
* Add a "where JSON not contains" clause to the query.
*
* @param string $column
* @param mixed $value
* @param string $boolean
* @return $this
*/
public function whereJsonNotContains($column, $value, $boolean = 'and')
{
return $this->whereJsonContains($column, $value, $boolean, true);
}

/**
* Add a "or where JSON not contains" clause to the query.
*
* @param string $column
* @param mixed $value
* @return $this
*/
public function orWhereJsonNotContains($column, $value)
{
return $this->whereJsonNotContains($column, $value, 'or');
}

/**
* Handles dynamic "where" clauses to the query.
*
Expand Down
4 changes: 3 additions & 1 deletion src/Illuminate/Database/Query/Grammars/Grammar.php
Original file line number Diff line number Diff line change
Expand Up @@ -499,7 +499,9 @@ protected function whereRowValues(Builder $query, $where)
*/
protected function whereJsonContains(Builder $query, $where)
{
return $this->compileJsonContains(
$not = $where['not'] ? 'not ' : '';

return $not.$this->compileJsonContains(
$this->wrap($where['column']), $this->parameter($where['value'])
);
}
Expand Down
44 changes: 44 additions & 0 deletions tests/Database/DatabaseQueryBuilderTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2656,6 +2656,50 @@ public function testWhereJsonContainsSqlServer()
$builder->select('*')->from('users')->whereJsonContains('options->languages', ['en'])->toSql();
}

public function testWhereJsonNotContainsMySql()
{
$builder = $this->getMySqlBuilder();
$builder->select('*')->from('users')->whereJsonNotContains('options->languages', ['en']);
$this->assertEquals('select * from `users` where not json_contains(`options`->\'$."languages"\', ?)', $builder->toSql());
$this->assertEquals(['["en"]'], $builder->getBindings());

$builder = $this->getMySqlBuilder();
$builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonNotContains('options->languages', new Raw("'[\"en\"]'"));
$this->assertEquals('select * from `users` where `id` = ? or not json_contains(`options`->\'$."languages"\', \'["en"]\')', $builder->toSql());
$this->assertEquals([1], $builder->getBindings());
}

public function testWhereJsonNotContainsPostgres()
{
$builder = $this->getPostgresBuilder();
$builder->select('*')->from('users')->whereJsonNotContains('options->languages', ['en']);
$this->assertEquals('select * from "users" where not ("options"->\'languages\')::jsonb @> ?', $builder->toSql());
$this->assertEquals(['["en"]'], $builder->getBindings());

$builder = $this->getPostgresBuilder();
$builder->select('*')->from('users')->where('id', '=', 1)->orWhereJsonNotContains('options->languages', new Raw("'[\"en\"]'"));
$this->assertEquals('select * from "users" where "id" = ? or not ("options"->\'languages\')::jsonb @> \'["en"]\'', $builder->toSql());
$this->assertEquals([1], $builder->getBindings());
}

/**
* @expectedException \RuntimeException
*/
public function testWhereJsonNotContainsSqlite()
{
$builder = $this->getSQLiteBuilder();
$builder->select('*')->from('users')->whereJsonNotContains('options->languages', ['en'])->toSql();
}

/**
* @expectedException \RuntimeException
*/
public function testWhereJsonNotContainsSqlServer()
{
$builder = $this->getSqlServerBuilder();
$builder->select('*')->from('users')->whereJsonNotContains('options->languages', ['en'])->toSql();
}

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

0 comments on commit 55a30f9

Please sign in to comment.