Skip to content

Commit 1e5c0b3

Browse files
josip-miloticJosip MilotićStyleCIBot
authored
Postgres ILIKE (#44)
* Added support for using ILIKE instead of LIKE on Postgres, parsing logic so that LIKE is used instead of in for single value * Apply fixes from StyleCI * Minor * Minor fix * Readme update Co-authored-by: Josip Milotić <josip.milotic@asseco-see.hr> Co-authored-by: StyleCI Bot <bot@styleci.io>
1 parent f329faa commit 1e5c0b3

File tree

6 files changed

+45
-10
lines changed

6 files changed

+45
-10
lines changed

README.md

+20-4
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,22 @@ can have micro-operators on them as well (i.e. `"column": "=value;!value2;%value
8888

8989
Example:
9090

91+
```
92+
{
93+
"search": {
94+
"first_name": "=foo1;foo2",
95+
"last_name": "!=bar1;bar2"
96+
}
97+
}
98+
```
99+
100+
Will perform a ``SELECT * FROM some_table WHERE first_name IN
101+
('foo1', 'foo2') AND last_name NOT IN ('bar1', 'bar2')``.
102+
103+
In case you pass a single value for a column on string type, LIKE operator will be used
104+
instead of IN. For Postgres databases, ILIKE is used instead of LIKE to support
105+
case-insensitive search.
106+
91107
```
92108
{
93109
"search": {
@@ -97,8 +113,8 @@ Example:
97113
}
98114
```
99115

100-
Will perform a ``SELECT * FROM some_table WHERE first_name IN
101-
('foo') AND last_name NOT IN ('bar')``.
116+
Will perform a ``SELECT * FROM some_table WHERE first_name LIKE 'foo' AND
117+
last_name NOT LIKE 'bar'``.
102118

103119
#### Micro operators
104120

@@ -120,8 +136,8 @@ single column (order matters!):
120136
}
121137
```
122138

123-
Will perform a ``SELECT * FROM some_table WHERE first_name NOT IN
124-
('foo') AND last_name LIKE 'bar%'``.
139+
Will perform a ``SELECT * FROM some_table WHERE first_name NOT LIKE
140+
'foo' AND last_name LIKE 'bar%'``.
125141

126142
Notice that here ``!value`` behaved the same as ``!=`` main operator. The difference
127143
is that ``!=`` main operator negates the complete list of values, whereas the

src/CategorizedValues.php

+9-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public function categorize()
6161
if ($this->isNegated($value)) {
6262
$value = $this->replaceNegation($value);
6363

64-
if ($this->hasWildCard($value)) {
64+
if ($this->hasWildCard($value) || $this->isSingleStringValue()) {
6565
$value = $this->replaceWildCard($value);
6666
$this->notLike[] = $value;
6767
continue;
@@ -71,7 +71,7 @@ public function categorize()
7171
continue;
7272
}
7373

74-
if ($this->hasWildCard($value)) {
74+
if ($this->hasWildCard($value) || $this->isSingleStringValue()) {
7575
$value = $this->replaceWildCard($value);
7676
$this->andLike[] = $value;
7777
continue;
@@ -116,4 +116,11 @@ protected function replaceNegation($value)
116116
{
117117
return preg_replace('~' . self::NOT . '~', '', $value, 1);
118118
}
119+
120+
// Hack so that LIKE operator is used when a single value of string type is passed.
121+
// Not happy with this solution, might need to refactor this later
122+
protected function isSingleStringValue(): bool
123+
{
124+
return count($this->searchParser->values) == 1 && $this->searchParser->type == 'string';
125+
}
119126
}

src/SearchCallbacks/AbstractCallback.php

+12
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
use Asseco\JsonQueryBuilder\Exceptions\JsonQueryBuilderException;
99
use Asseco\JsonQueryBuilder\SearchParser;
1010
use Illuminate\Database\Eloquent\Builder;
11+
use Illuminate\Support\Facades\DB;
1112
use Illuminate\Support\Str;
13+
use PDO;
1214

1315
abstract class AbstractCallback
1416
{
@@ -153,4 +155,14 @@ protected function isDate(string $type): bool
153155
{
154156
return in_array($type, self::DATE_FIELDS);
155157
}
158+
159+
//Hack to enable case-insensitive search when using PostgreSQL database
160+
protected function getLikeOperator(): string
161+
{
162+
if (DB::connection()->getPDO()->getAttribute(PDO::ATTR_DRIVER_NAME) == 'pgsql') {
163+
return 'ILIKE';
164+
}
165+
166+
return 'LIKE';
167+
}
156168
}

src/SearchCallbacks/Equals.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ public static function operator(): string
2626
public function execute(Builder $builder, string $column, CategorizedValues $values): void
2727
{
2828
foreach ($values->andLike as $andLike) {
29-
$builder->where($column, 'LIKE', $andLike);
29+
$builder->where($column, $this->getLikeOperator(), $andLike);
3030
}
3131

3232
foreach ($values->notLike as $notLike) {
33-
$builder->where($column, 'NOT LIKE', $notLike);
33+
$builder->where($column, 'NOT ' . $this->getLikeOperator(), $notLike);
3434
}
3535

3636
if ($values->null) {

src/SearchCallbacks/NotEquals.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public function execute(Builder $builder, string $column, CategorizedValues $val
3030
throw new Exception('Not operator is not supported for date(time) fields');
3131
}
3232

33-
$builder->where($column, 'NOT LIKE', $like);
33+
$builder->where($column, 'NOT ' . $this->getLikeOperator(), $like);
3434
}
3535

3636
if ($values->null || $values->notNull) {

src/SearchParser.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ protected function parseOperator($operators, string $argument): string
8181
* Output: val1
8282
* val2
8383
*
84-
* @param $values
84+
* @param string $values
8585
* @return array
8686
*
8787
* @throws JsonQueryBuilderException

0 commit comments

Comments
 (0)