diff --git a/src/Database/Database.php b/src/Database/Database.php index 8e1b60556..c97b827e4 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -7856,8 +7856,8 @@ public function find(string $collection, array $queries = [], string $forPermiss } /** - * Call callback for each document of the given collection - * that matches the given queries + * Helper method to iterate documents in collection using callback pattern + * Alterative is * * @param string $collection * @param callable $callback @@ -7867,6 +7867,23 @@ public function find(string $collection, array $queries = [], string $forPermiss * @throws \Utopia\Database\Exception */ public function foreach(string $collection, callable $callback, array $queries = [], string $forPermission = Database::PERMISSION_READ): void + { + foreach ($this->iterate($collection, $queries, $forPermission) as $document) { + $callback($document); + } + } + + /** + * Return each document of the given collection + * that matches the given queries + * + * @param string $collection + * @param array $queries + * @param string $forPermission + * @return \Generator + * @throws \Utopia\Database\Exception + */ + public function iterate(string $collection, array $queries = [], string $forPermission = Database::PERMISSION_READ): \Generator { $grouped = Query::groupByType($queries); $limitExists = $grouped['limit'] !== null; @@ -7906,9 +7923,7 @@ public function foreach(string $collection, callable $callback, array $queries = $sum = count($results); foreach ($results as $document) { - if (is_callable($callback)) { - $callback($document); - } + yield $document; } $latestDocument = $results[array_key_last($results)]; diff --git a/tests/e2e/Adapter/Scopes/DocumentTests.php b/tests/e2e/Adapter/Scopes/DocumentTests.php index 868ffc84c..f3d9d937e 100644 --- a/tests/e2e/Adapter/Scopes/DocumentTests.php +++ b/tests/e2e/Adapter/Scopes/DocumentTests.php @@ -4014,6 +4014,26 @@ public function testForeach(): void /** @var Database $database */ $database = $this->getDatabase(); + /** + * Test, foreach generator on empty collection + */ + $database->createCollection('moviesEmpty'); + $documents = []; + foreach ($database->iterate('moviesEmpty', queries: [Query::limit(2)]) as $document) { + $documents[] = $document; + } + $this->assertEquals(0, \count($documents)); + $this->assertTrue($database->deleteCollection('moviesEmpty')); + + /** + * Test, foreach generator + */ + $documents = []; + foreach ($database->iterate('movies', queries: [Query::limit(2)]) as $document) { + $documents[] = $document; + } + $this->assertEquals(6, count($documents)); + /** * Test, foreach goes through all the documents */