Skip to content

Commit 19f4196

Browse files
committed
wip
1 parent 1b4c563 commit 19f4196

File tree

7 files changed

+402
-232
lines changed

7 files changed

+402
-232
lines changed

src/DatabaseGrammarFactory.php

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,11 @@ public static function make(Connection $connection): SearchGrammarInterface
2929
{
3030
$driver = $connection->getDriverName();
3131

32-
switch ($driver) {
33-
case 'mysql':
34-
case 'mariadb':
35-
return new MySqlSearchGrammar($connection);
36-
case 'pgsql':
37-
return new PostgreSqlSearchGrammar($connection);
38-
case 'sqlite':
39-
return new SQLiteSearchGrammar($connection);
40-
default:
41-
throw InvalidGrammarException::driverNotSupported($driver);
42-
}
32+
return match ($driver) {
33+
'mysql', 'mariadb' => new MySqlSearchGrammar($connection),
34+
'pgsql' => new PostgreSqlSearchGrammar($connection),
35+
'sqlite' => new SQLiteSearchGrammar($connection),
36+
default => throw InvalidGrammarException::driverNotSupported($driver),
37+
};
4338
}
4439
}

src/Grammars/MySqlSearchGrammar.php

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,14 @@
1313
*/
1414
class MySqlSearchGrammar implements SearchGrammarInterface
1515
{
16-
protected Connection $connection;
17-
1816
protected MySqlGrammar $grammar;
1917

2018
/**
2119
* Create a new MySQL search grammar instance.
2220
*/
23-
public function __construct(Connection $connection)
21+
public function __construct(protected Connection $connection)
2422
{
25-
$this->connection = $connection;
26-
$this->grammar = new MySqlGrammar($connection);
23+
$this->grammar = new MySqlGrammar($this->connection);
2724
}
2825

2926
public function wrap(string|Expression $value): string

src/Grammars/PostgreSqlSearchGrammar.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ public function __construct(protected Connection $connection)
2525

2626
public function wrap(string|Expression $value): string
2727
{
28+
// Handle JSON columns specially for PostgreSQL
29+
if (is_string($value) && str_contains($value, '->>')) {
30+
// Split the JSON column path for proper wrapping
31+
[$table_column, $jsonPath] = explode('->>', $value, 2);
32+
// For PostgreSQL, we need to cast string columns to JSON first when using JSON operators
33+
return "(" . $this->grammar->wrap($table_column) . ")::json->>" . $jsonPath;
34+
}
35+
2836
return $this->grammar->wrap($value);
2937
}
3038

@@ -33,6 +41,17 @@ public function wrap(string|Expression $value): string
3341
*/
3442
public function caseInsensitive(string $column): string
3543
{
44+
// Handle JSON columns by casting to text first for PostgreSQL
45+
if (str_contains($column, '->>')) {
46+
// First cast the base column to JSON, then extract the value, then cast to text
47+
$parts = explode('->>', $column, 2);
48+
if (count($parts) === 2) {
49+
$baseColumn = $parts[0];
50+
$jsonPath = $parts[1];
51+
return "LOWER(({$baseColumn})::json->>{$jsonPath}::text)";
52+
}
53+
}
54+
3655
return "LOWER({$column})";
3756
}
3857

src/Grammars/SQLiteSearchGrammar.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,14 @@
1313
*/
1414
class SQLiteSearchGrammar implements SearchGrammarInterface
1515
{
16-
protected Connection $connection;
17-
1816
protected SQLiteGrammar $grammar;
1917

2018
/**
2119
* Create a new SQLite search grammar instance.
2220
*/
23-
public function __construct(Connection $connection)
21+
public function __construct(protected Connection $connection)
2422
{
25-
$this->connection = $connection;
26-
$this->grammar = new SQLiteGrammar($connection);
23+
$this->grammar = new SQLiteGrammar($this->connection);
2724
}
2825

2926
public function wrap(string|Expression $value): string
@@ -46,7 +43,7 @@ public function coalesce(array $values): string
4643
{
4744
// SQLite requires at least 2 arguments for COALESCE
4845
if (count($values) === 1) {
49-
return (string) $values[0];
46+
return $values[0];
5047
}
5148

5249
$valueList = implode(',', $values);

src/ModelToSearchThrough.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,15 @@
66

77
use Illuminate\Database\Eloquent\Builder;
88
use Illuminate\Database\Eloquent\Model;
9+
use Illuminate\Database\Query\Expression;
910
use Illuminate\Support\Collection;
1011
use Illuminate\Support\Str;
1112

1213
readonly class ModelToSearchThrough
1314
{
1415
/**
1516
* @param Builder<Model> $builder Builder to search through
16-
* @param Collection<int, string> $columns The columns to search through
17+
* @param Collection<int, string|Expression> $columns The columns to search through
1718
* @param string $orderByColumn Order column
1819
* @param int $key Unique key of this instance
1920
* @param bool $fullText Full-text search
@@ -59,7 +60,7 @@ public function getFreshBuilder(): Builder
5960
/**
6061
* Get a collection with all columns or relations to search through.
6162
*
62-
* @return Collection<int, string>
63+
* @return Collection<int, string|Expression>
6364
*/
6465
public function getColumns(): Collection
6566
{
@@ -69,7 +70,7 @@ public function getColumns(): Collection
6970
/**
7071
* Create a new instance with different columns to search through.
7172
*
72-
* @param Collection<int, string> $columns
73+
* @param Collection<int, string|Expression> $columns
7374
*/
7475
public function setColumns(Collection $columns): self
7576
{
@@ -88,11 +89,11 @@ public function setColumns(Collection $columns): self
8889
* Get a collection with all qualified columns
8990
* to search through.
9091
*
91-
* @return Collection<int, string>
92+
* @return Collection<int, string|Expression>
9293
*/
9394
public function getQualifiedColumns(): Collection
9495
{
95-
return $this->columns->map(fn (string $column) => $this->qualifyColumn($column));
96+
return $this->columns->map(fn($column): \Illuminate\Database\Query\Expression|string => $column instanceof Expression ? $column : $this->qualifyColumn($column));
9697
}
9798

9899
/**
@@ -125,6 +126,14 @@ public function qualifyColumn(string $column): string
125126
return $this->getModel()->qualifyColumn($column);
126127
}
127128

129+
/**
130+
* Check if a column is a raw expression.
131+
*/
132+
public function isRawExpression(mixed $column): bool
133+
{
134+
return $column instanceof Expression;
135+
}
136+
128137
/**
129138
* Get the qualified key name.
130139
*/

0 commit comments

Comments
 (0)