db icon indicating copy to clipboard operation
db copied to clipboard

Add `each()` to `QueryInterface`

Open SamMousa opened this issue 8 years ago • 2 comments

In QueryInterface it seems some functions are missing:

public function each()
public function batch()

In Query, these functions return BatchQueryResult. Since from an API perspective BatchQueryResult is equal to Iterator, I propose changing the return type to iterable.

By doing this any QueryInterface implementation can simply implement these functions (we could even implement a basic trait) in an inefficient way:

public function each() {
    return $this->all(); // An array is already iterable.
}

// Taken from: https://github.com/nikic/iter/blob/master/src/iter.php#L802
public function batch($100) {
    $chunk = [];
    $count = 0;
    foreach ($this->each() as $key => $value) {
        $chunk[$key] = $value;
        $count++;
        if ($count === $size) {
            yield $chunk;
            $count = 0;
            $chunk = [];
        }
    }
    if ($count !== 0) {
        yield $chunk;
    }
}

Motivation

When creating objects that consume a QueryInterface, what matters not is implementation, but intended use. When I consume an implementation I want to let it know that I'll be iterating over the objects one by one (each), it should, if possible, do something smart with that information.

Currently I either type hint to a specific implementation or I call functions not on the interface, both are not satisfactory. If I use Mongo for example, it has an implementation for each: https://github.com/yiisoft/yii2-mongodb/blob/master/Query.php#L302 However I cannot use this without explicitly adapting my code.

  • If I typehint the Query implemention in the framework the precondition will fail (Mongo extension Query does not extend yii\db\Query).
  • If I typehint QueryInterface I cannot call each() without making assumptions that might not be valid.

Backwards compatibility

This will break backwards compatibility for third party QueryInterface implementations, these will need to implement this functionality manually or use the trait containing the frameworks' implementations.

SamMousa avatar Sep 15 '17 07:09 SamMousa

BC: can create new interface for this features?

bscheshirwork avatar Sep 15 '17 07:09 bscheshirwork

Something like IterableQueryInterface = QueryInterface + Iterator

bscheshirwork avatar Sep 15 '17 08:09 bscheshirwork

done.

terabytesoftw avatar Feb 26 '23 17:02 terabytesoftw