1+ <?php
2+
3+ declare (strict_types=1 );
4+
5+ namespace ProtoneMedia \LaravelCrossEloquentSearch \Grammars ;
6+
7+ use Illuminate \Contracts \Database \Query \Expression ;
8+ use Illuminate \Database \Connection ;
9+ use Illuminate \Database \Query \Grammars \PostgresGrammar ;
10+
11+ /**
12+ * PostgreSQL-specific search grammar implementation.
13+ */
14+ class PostgreSqlSearchGrammar implements SearchGrammarInterface
15+ {
16+ protected PostgresGrammar $ grammar ;
17+
18+ /**
19+ * Create a new PostgreSQL search grammar instance.
20+ */
21+ public function __construct (protected Connection $ connection )
22+ {
23+ $ this ->grammar = new PostgresGrammar ($ this ->connection );
24+ }
25+
26+ public function wrap (string |Expression $ value ): string
27+ {
28+ return $ this ->grammar ->wrap ($ value );
29+ }
30+
31+ /**
32+ * Create a case-insensitive column expression.
33+ */
34+ public function caseInsensitive (string $ column ): string
35+ {
36+ return "LOWER( {$ column }) " ;
37+ }
38+
39+ /**
40+ * @param array<int, string> $values
41+ */
42+ public function coalesce (array $ values ): string
43+ {
44+ $ valueList = implode (', ' , $ values );
45+
46+ return "COALESCE( {$ valueList }) " ;
47+ }
48+
49+ /**
50+ * Create a character length expression for the given column.
51+ */
52+ public function charLength (string $ column ): string
53+ {
54+ return "CHAR_LENGTH( {$ column }) " ;
55+ }
56+
57+ /**
58+ * Create a string replace expression.
59+ */
60+ public function replace (string $ column , string $ search , string $ replace ): string
61+ {
62+ return "REPLACE( {$ column }, {$ search }, {$ replace }) " ;
63+ }
64+
65+ /**
66+ * Create a lowercase expression for the given column.
67+ */
68+ public function lower (string $ column ): string
69+ {
70+ return "LOWER( {$ column }) " ;
71+ }
72+
73+ /**
74+ * Get the operator used for phonetic/sounds-like matching.
75+ */
76+ public function soundsLikeOperator (): string
77+ {
78+ // PostgreSQL doesn't have a built-in SOUNDS LIKE operator
79+ // Could use extensions like fuzzystrmatch with soundex() function
80+ // For now, fall back to ILIKE for case-insensitive matching
81+ return 'ilike ' ;
82+ }
83+
84+ /**
85+ * Check if the database supports phonetic/sounds-like matching.
86+ */
87+ public function supportsSoundsLike (): bool
88+ {
89+ // PostgreSQL supports phonetic matching through extensions like fuzzystrmatch
90+ // However, we'll return false for the basic implementation to keep it simple
91+ // Users can enable the extension and customize this if needed
92+ return false ;
93+ }
94+
95+ /**
96+ * Check if the database supports complex ordering in UNION queries.
97+ */
98+ public function supportsUnionOrdering (): bool
99+ {
100+ // PostgreSQL doesn't support complex ORDER BY expressions in UNION queries
101+ // Similar to SQLite, we need to wrap the UNION in a subquery
102+ return false ;
103+ }
104+
105+ /**
106+ * Wrap a UNION query for databases that need special handling.
107+ *
108+ * @param array<int, mixed> $bindings
109+ * @return array<string, mixed>
110+ */
111+ public function wrapUnionQuery (string $ sql , array $ bindings ): array
112+ {
113+ return [
114+ 'sql ' => "( {$ sql }) as union_results " ,
115+ 'bindings ' => $ bindings ,
116+ ];
117+ }
118+ }
0 commit comments