1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
<?php
namespace ipl\Sql\Compat;
use InvalidArgumentException;
use ipl\Sql\Filter\Exists;
use ipl\Sql\Filter\NotExists;
use ipl\Sql\Sql;
use ipl\Stdlib\Filter;
class FilterProcessor
{
public static function assembleFilter(Filter\Rule $filter, $level = 0)
{
$condition = null;
if ($filter instanceof Filter\Chain) {
if ($filter instanceof Filter\All) {
$operator = Sql::ALL;
} elseif ($filter instanceof Filter\Any) {
$operator = Sql::ANY;
} elseif ($filter instanceof Filter\None) {
$operator = Sql::NOT_ALL;
}
if (! isset($operator)) {
throw new InvalidArgumentException(sprintf('Cannot render filter: %s', get_class($filter)));
}
if (! $filter->isEmpty()) {
foreach ($filter as $filterPart) {
$part = static::assembleFilter($filterPart, $level + 1);
if ($part) {
if ($condition === null) {
$condition = [$operator, [$part]];
} else {
if ($condition[0] === $operator) {
$condition[1][] = $part;
} elseif ($operator === Sql::NOT_ALL) {
$condition = [Sql::ALL, [$condition, [$operator, [$part]]]];
} elseif ($operator === Sql::NOT_ANY) {
$condition = [Sql::ANY, [$condition, [$operator, [$part]]]];
} else {
$condition = [$operator, [$condition, $part]];
}
}
}
}
} else {
// TODO(el): Explicitly return the empty string due to the FilterNot case?
}
} else {
/** @var Filter\Condition $filter */
$condition = [Sql::ALL, static::assemblePredicate($filter)];
}
return $condition;
}
public static function assemblePredicate(Filter\Condition $filter)
{
$column = $filter->getColumn();
$expression = $filter->getValue();
if (is_array($expression)) {
if ($filter instanceof Filter\UnEqual || $filter instanceof Filter\Unlike) {
return ["($column NOT IN (?) OR $column IS NULL)" => $expression];
} elseif ($filter instanceof Filter\Equal || $filter instanceof Filter\Like) {
return ["$column IN (?)" => $expression];
}
throw new InvalidArgumentException(
'Unable to render array expressions with operators other than equal or not equal'
);
} elseif (
($filter instanceof Filter\Like || $filter instanceof Filter\Unlike)
&& strpos($expression, '*') !== false
) {
if ($expression === '*') {
return ["$column IS " . ($filter instanceof Filter\Like ? 'NOT ' : '') . 'NULL'];
} elseif ($filter instanceof Filter\Unlike) {
return ["($column NOT LIKE ? OR $column IS NULL)" => str_replace('*', '%', $expression)];
} else {
return ["$column LIKE ?" => str_replace('*', '%', $expression)];
}
} elseif ($filter instanceof Filter\Unequal || $filter instanceof Filter\Unlike) {
return ["($column != ? OR $column IS NULL)" => $expression];
} else {
if ($filter instanceof Filter\Like || $filter instanceof Filter\Equal) {
$operator = '=';
} elseif ($filter instanceof Filter\GreaterThan) {
$operator = '>';
} elseif ($filter instanceof Filter\GreaterThanOrEqual) {
$operator = '>=';
} elseif ($filter instanceof Filter\LessThan) {
$operator = '<';
} elseif ($filter instanceof Filter\LessThanOrEqual) {
$operator = '<=';
} elseif ($filter instanceof Exists) {
$operator = 'EXISTS';
} elseif ($filter instanceof NotExists) {
$operator = 'NOT EXISTS';
} else {
throw new InvalidArgumentException(sprintf('Cannot render filter: %s', get_class($filter)));
}
return ["$column $operator ?" => $expression];
}
}
}
|