zendframework/zend-db

Add, rather than replace, columns in a select

Closed this issue · 3 comments

I have a use case in which I'd like to (at various points before executing a query) add columns to my select. Contrived example:

$resultSet = $this->select(function($select) use($options) {

  if($options['includeSomething']) {
    $select->columns('something');
  }

  if($options['includeOtherThing']) {
    $select->columns('other_thing');
  }

});

I've found that's not possible, because:

  • select.columns() replaces the query columns each time
  • select.columns is protected, meaning I can't get at it to merge with before calling select.columns()

Would you be receptive to a PR that did one of these things:

  • Add a getter / made select.columns public
  • Add a merge param to select.columns()
  • Add a select.addColumns() method

Sorry if this is in a strange place, or seems like a strange request! I am a new ZF2 user, and have had a look over the source and am reasonably sure this isn't possible currently (though I could be wrong!).

I know it should be possible to extend the Select class and implement these things myself. But I'm not quite sure how to get ZF2 to then use my extended class.

Thanks!

What about simply using an array?

$resultSet = $this->select(function ($select) use ($options) {
    $columns = array();

    if ($options['includeSomething']) {
        $columns[] = 'something';
    }

    if ($options['includeOtherThing']) {
        $columns[] = 'other_thing';
    }

    $select->columns($columns);
});

The easiest way is to collect columns in an array and setting this array in a final step. However I ran into situations where I had to manipulate an existing Select object with an unknown existing column set. This can also be done:

$columns = $select->getRawState(Select::COLUMNS);
$columns[] = 'foo';
$select->columns($columns);

This allows any manipulation, not just adding columns. But I agree, for the common task of adding a column, there should be a more straightforward method.

Thanks @hschletz, that looks exactly like what I wanted to do!