nozavroni / csvelte

🕺🏻 CSV and Tabular Data library for PHP
http://phpcsv.com/
Other
6 stars 0 forks source link

Stream Decorators: Multiple (alternate/collate) Streams #140

Open nozavroni opened 7 years ago

nozavroni commented 7 years ago

I'm not sure how useful (if at all) this would be, but what if there was a way to pass in an array of IO\Resource objects as the output destination. The class would be able to accept an anonymous function that would tell the write operation(s) which stream to write to. For example:

MultiStream (writer)

$stream = new CollateStream([
    'foo' => new Resource('./data/products1.csv'),
    'bar' => new Resource('./data/products2.csv'),
    'baz' => new Resource('./data/products2.csv'),
]);
$stream->setDecider(function($self, $data, $resArr) {
    // return whichever one is the smallest
    return collect($resArr)->reduce(function($last, $current) {
        return ($last()->getSize() > $current()->getSize()) ?
            $current : 
            $last;
    })->key();
});

The default decider function would do its best to ensure that all streams stayed about the same size. An example of a useful user-defined decider function would be one that writes to one stream until it reaches a given size, at which time it creates a new file and begins writing to that one. This would effectively give you a directory of products1.csv, products2.csv, products2.csv, etc. All of which would be certain to be under a given size. Then, to stitch them back together, you could use a MultiReaderStream (opposite of what I just showed you).

MultiStream (reader)

$stream = new GlobStream('./data/*.csv');
$stream->readLine(); // would fetch from one of the files in './data' directory