diff options
Diffstat (limited to 'vendor/ipl/sql/src/Compat')
-rw-r--r-- | vendor/ipl/sql/src/Compat/FilterProcessor.php | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/vendor/ipl/sql/src/Compat/FilterProcessor.php b/vendor/ipl/sql/src/Compat/FilterProcessor.php new file mode 100644 index 0000000..7d779d7 --- /dev/null +++ b/vendor/ipl/sql/src/Compat/FilterProcessor.php @@ -0,0 +1,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]; + } + } +} |