omines / datatables-bundle

DataTables bundle for Symfony
https://omines.github.io/datatables-bundle/
MIT License
255 stars 114 forks source link

Add result transformer #142

Closed danut007ro closed 4 years ago

danut007ro commented 4 years ago

This pull request aims to add a result transformer that behaves just like the row transformer (formatter).

It allows to do a post-processing for entire result, not only for a row. I use it for a custom PromiseColumn where I collect all the rows and make a single call to database to get result for each row, instead of making as many calls as rows.

I couldn't find any other way of having this functionality and it looks useful. Tests included.

Thanks.

curry684 commented 4 years ago

What case does this solve that the regular transformer option doesn't already provide?

Oh I see. I understand where you're coming from, but it's implemented at the wrong level now - you're depending on the Adapter implementation to 'respect' a setting at the DataTable level, causing a reverse dependency.

I'm also not sure there is a right solution at this level, given what we mentioned before about the bundle assuming row-based operations at all levels. Shouldn't you just be writing a custom adapter, which could have its own options like set-based transforms? It really sounds like you need something like a LazyDataAdapter instead.

danut007ro commented 4 years ago

The regular transformer doesn't allow to process the entire result in bulk, only one by one. In my case I needed the bulk processing to use promises.

danut007ro commented 4 years ago

Oh I see. I will try the LazyDataAdapter way. Unfortunatelly that will be mostly copy-pasted from ORMAdapter and also AbstractAdapter (close to 100% + my transformer code). That's why I was searching for an alternative solution.

curry684 commented 4 years ago

No you wouldn't need to copy/paste much, just implement a Decorator:

class LazyAdapter implements AdapterInterface
{
    private $wrapper;

    public function __construct(AdapterInterface $wrapper)
    {
        $this->wrapper = $wrapper;
    }

    public function configure(array $options)
    {
        $this->wrapper->configure($options);
    }

    public function getData(DataTableState $state): ResultSetInterface
    {
        $dataset = $this->wrapper->getData($state);
        foreach ($dataset->getData() as $row) {
            // Do stuff
        }
        return $dataset;
    }
}
danut007ro commented 4 years ago

Thank you. Will try and see how it goes. This will be my last pull request related to result transformers, I promise :)