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