Skip to content

Filter expressions #30

@nilmerg

Description

@nilmerg

With 8ce7d5c, 12a46ca and 0a68c04 I've added classes that resemble specific SQL where expressions. But these are currently implemented in a way they play fine with other code handling filters. (e.g. ipl\Orm\Compat\FilterProcessor) This leads to unnecessary cases like this and of course bogus interface implementations. (All of them have either no value or no column)

What I'd like to see is a more generic filter object that can handle all of these cases (plus more) and plays fine with other code handling filter objects. Heck, it should even be possible to still make use of things like RewriteFilter objects so that the columns and values of a expression are processed.

My first concept of this object looks like this:

namespace ipl\Sql\Filter;

use ipl\Sql\ExpressionInterface;
use ipl\Stdlib\Filter;

class Expression implements ExpressionInterface, Filter\Rule
{
    protected $statement;

    protected $columns;

    public function __construct($statement, array $columns)
    {
        $this->statement = $statement;
        $this->columns = $columns;
    }

    public function getStatement()
    {
        return sprintf($this->statement, ...$this->getColumns());
    }

    public function getColumns()
    {
        return array_keys($this->columns);
    }

    public function setColumns(array $columns)
    {
        $this->columns = $columns;

        return $this;
    }

    public function getValues()
    {
        return array_values($this->columns);
    }
}

Usage would look this way:

use ipl\Sql\Filter\Expression;

// ipl\Sql\Select objects would need to be handled just like columns, because objects can't be keys.....
$exists = new Expression('EXISTS(%s)', [ipl\Sql\Select]);
$notExists = new Expression('NOT EXISTS(%s)', [ipl\Sql\Select]);

// Values are processed just as usual, columns will be inserted into the statement by the object itself.
// Separating them anyway allows pre-processing to happen.
$isNull = new Expression('%s IS NULL', ['id' => null]);
$case = new Expression('CASE WHEN %s = ? OR %s = ? THEN 1 ELSE 0 END', ['name' => 'foo', 'name' => 'bar']);

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions