Skip to content

Commit 5d9cf9c

Browse files
Add SQLite support for whereJsonContains method (#49401)
1 parent 4861acf commit 5d9cf9c

File tree

2 files changed

+39
-4
lines changed

2 files changed

+39
-4
lines changed

src/Illuminate/Database/Query/Grammars/SQLiteGrammar.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,31 @@ protected function compileJsonLength($column, $operator, $value)
146146
return 'json_array_length('.$field.$path.') '.$operator.' '.$value;
147147
}
148148

149+
/**
150+
* Compile a "JSON contains" statement into SQL.
151+
*
152+
* @param string $column
153+
* @param mixed $value
154+
* @return string
155+
*/
156+
protected function compileJsonContains($column, $value)
157+
{
158+
[$field, $path] = $this->wrapJsonFieldAndPath($column);
159+
160+
return 'exists (select 1 from json_each('.$field.$path.') where '.$this->wrap('json_each.value').' is '.$value.')';
161+
}
162+
163+
/**
164+
* Prepare the binding for a "JSON contains" statement.
165+
*
166+
* @param mixed $binding
167+
* @return mixed
168+
*/
169+
public function prepareBindingForJsonContains($binding)
170+
{
171+
return $binding;
172+
}
173+
149174
/**
150175
* Compile a "JSON contains key" statement into SQL.
151176
*

tests/Database/DatabaseQueryBuilderTest.php

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5192,10 +5192,15 @@ public function testWhereJsonContainsPostgres()
51925192

51935193
public function testWhereJsonContainsSqlite()
51945194
{
5195-
$this->expectException(RuntimeException::class);
5195+
$builder = $this->getSQLiteBuilder();
5196+
$builder->select('*')->from('users')->whereJsonContains('options', 'en')->toSql();
5197+
$this->assertSame('select * from "users" where exists (select 1 from json_each("options") where "json_each"."value" is ?)', $builder->toSql());
5198+
$this->assertEquals(['en'], $builder->getBindings());
51965199

51975200
$builder = $this->getSQLiteBuilder();
5198-
$builder->select('*')->from('users')->whereJsonContains('options->languages', ['en'])->toSql();
5201+
$builder->select('*')->from('users')->whereJsonContains('users.options->language', 'en')->toSql();
5202+
$this->assertSame('select * from "users" where exists (select 1 from json_each("users"."options", \'$."language"\') where "json_each"."value" is ?)', $builder->toSql());
5203+
$this->assertEquals(['en'], $builder->getBindings());
51995204
}
52005205

52015206
public function testWhereJsonContainsSqlServer()
@@ -5244,10 +5249,15 @@ public function testWhereJsonDoesntContainPostgres()
52445249

52455250
public function testWhereJsonDoesntContainSqlite()
52465251
{
5247-
$this->expectException(RuntimeException::class);
5252+
$builder = $this->getSQLiteBuilder();
5253+
$builder->select('*')->from('users')->whereJsonDoesntContain('options', 'en')->toSql();
5254+
$this->assertSame('select * from "users" where not exists (select 1 from json_each("options") where "json_each"."value" is ?)', $builder->toSql());
5255+
$this->assertEquals(['en'], $builder->getBindings());
52485256

52495257
$builder = $this->getSQLiteBuilder();
5250-
$builder->select('*')->from('users')->whereJsonDoesntContain('options->languages', ['en'])->toSql();
5258+
$builder->select('*')->from('users')->whereJsonDoesntContain('users.options->language', 'en')->toSql();
5259+
$this->assertSame('select * from "users" where not exists (select 1 from json_each("users"."options", \'$."language"\') where "json_each"."value" is ?)', $builder->toSql());
5260+
$this->assertEquals(['en'], $builder->getBindings());
52515261
}
52525262

52535263
public function testWhereJsonDoesntContainSqlServer()

0 commit comments

Comments
 (0)