db
db copied to clipboard
Add `each()` to `QueryInterface`
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
Queryimplemention in the framework the precondition will fail (Mongo extensionQuerydoes not extendyii\db\Query). - If I typehint
QueryInterfaceI cannot calleach()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.
BC: can create new interface for this features?
Something like IterableQueryInterface = QueryInterface + Iterator
done.