Skip to content

Initial support for '&&' operator used for arrays in PostgreSQL. #14

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jul 26, 2017

Conversation

dorantor
Copy link
Contributor

@dorantor dorantor commented May 8, 2017

Very basic support. Not very convenient, because at this level, all array conversion have to be done in app:

        $items = $this->query('item')
            ->where('categories_ids', '&&', '{' . $category->id() . '}')
            ->find()
        ;

or

        $items = $this->query('item')
            ->where('categories_ids', '&&', '{' . implode(',' $ids) . '}')
            ->find()
        ;

But it is already working and allows to use pgsql arrays. Ideally, it should be

        $ids = array(1, 2, 3);
        $items = $this->query('item')
            ->where('categories_ids', '&&', $ids)
            ->find()
        ;

But there are two major stoppers for me:

  • arrays in pgsql could be nested(but I can avoid this, saying that I will deal only with "flat" arrays)
  • more importantly, I don't know where to put this conversion. And this conversion should be two way and support should be not only for && operator, but also for select, insert, update, delete and, probably, somewhere else also.

As an option, I can start with baby steps. Add conversion just for && operator, for example. But I need some guidance here :)

@dracony
Copy link
Member

dracony commented May 8, 2017

Ok, so basically the correct way to do this is:

  1. change $addtionalOperators to define a new operatorgroup:
protected $additionalOperators = array(
    'compare'   => array('>>', '>>=', '<<', '<<=', '&&',),
    'array'   => array('in array', 'not in array') // define an 'array' operator group with 2 operators
);
  1. Then you want to add a method to handles this operator group. It has to be called 'parse' + nameOfTheGroup:
    protected function parseArray($field, $operator, $values)
    {
        $value = $this->singleValue($values, $operator); // get the parameter
        $operator = $operator == 'in array' ? '&&' : '!&&'; // convert text operator to actual postgre operator
         // idk if !&& actually exists or not, but just an example
        $expr = $this->prefix($field, $operator);
        $expr->sql.= '{' . implode(',' $ids) . '}';
        return $expr;
    }

Smth like this :)

@dorantor
Copy link
Contributor Author

Finally found some time to finish this. Now it should work in "ideal" fashion:

        $ids = array(1, 2, 3);
        $items = $this->query('item')
            ->where('categories_ids', '&&', $ids)
            ->find()
        ;

Haven't tried in my projects yet, but tests are passing :)
Important note. I need it only with int s, so this is the only type supported in arrays for now.

@dracony dracony merged commit 6b3adf8 into PHPixie:master Jul 26, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants