Commit a0cc581b authored by Marco Pivetta's avatar Marco Pivetta Committed by GitHub

Merge pull request #2718 from jenkoian/efficient-iterating

Add iterators for non pdo drivers.
parents 373ae9ed 078d32ea
......@@ -20,6 +20,7 @@
namespace Doctrine\DBAL\Driver\IBMDB2;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
class DB2Statement implements \IteratorAggregate, Statement
{
......@@ -199,9 +200,7 @@ class DB2Statement implements \IteratorAggregate, Statement
*/
public function getIterator()
{
$data = $this->fetchAll();
return new \ArrayIterator($data);
return new StatementIterator($this);
}
/**
......
......@@ -20,6 +20,7 @@
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use PDO;
/**
......@@ -406,8 +407,6 @@ class MysqliStatement implements \IteratorAggregate, Statement
*/
public function getIterator()
{
$data = $this->fetchAll();
return new \ArrayIterator($data);
return new StatementIterator($this);
}
}
......@@ -21,7 +21,6 @@ namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\Connection;
use Doctrine\DBAL\Driver\ServerInfoAwareConnection;
use Doctrine\DBAL\Platforms\OraclePlatform;
/**
* OCI8 implementation of the Connection interface.
......
......@@ -20,6 +20,8 @@
namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use IteratorAggregate;
use PDO;
/**
......@@ -28,7 +30,7 @@ use PDO;
* @since 2.0
* @author Roman Borschel <roman@code-factory.org>
*/
class OCI8Statement implements \IteratorAggregate, Statement
class OCI8Statement implements IteratorAggregate, Statement
{
/**
* @var resource
......@@ -369,9 +371,7 @@ class OCI8Statement implements \IteratorAggregate, Statement
*/
public function getIterator()
{
$data = $this->fetchAll();
return new \ArrayIterator($data);
return new StatementIterator($this);
}
/**
......
......@@ -19,6 +19,7 @@
namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\StatementIterator;
use IteratorAggregate;
use PDO;
use Doctrine\DBAL\Driver\Statement;
......@@ -278,7 +279,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
*/
public function getIterator()
{
return new \ArrayIterator($this->fetchAll());
return new StatementIterator($this);
}
/**
......
......@@ -19,6 +19,7 @@
namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\StatementIterator;
use PDO;
use IteratorAggregate;
use Doctrine\DBAL\Driver\Statement;
......@@ -295,9 +296,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
*/
public function getIterator()
{
$data = $this->fetchAll();
return new \ArrayIterator($data);
return new StatementIterator($this);
}
/**
......
<?php
namespace Doctrine\DBAL\Driver;
class StatementIterator implements \IteratorAggregate
{
/**
* @var Statement
*/
private $statement;
/**
* @param Statement $statement
*/
public function __construct(Statement $statement)
{
$this->statement = $statement;
}
/**
* {@inheritdoc}
*/
public function getIterator()
{
while (false !== ($result = $this->statement->fetch())) {
yield $result;
}
}
}
<?php
namespace Doctrine\Tests\DBAL\Driver;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
class StatementIteratorTest extends \Doctrine\Tests\DbalTestCase
{
public function testGettingIteratorDoesNotCallFetch()
{
$stmt = $this->createMock(Statement::class);
$stmt->expects($this->never())->method('fetch');
$stmt->expects($this->never())->method('fetchAll');
$stmt->expects($this->never())->method('fetchColumn');
$stmtIterator = new StatementIterator($stmt);
$stmtIterator->getIterator();
}
public function testIterationCallsFetchOncePerStep()
{
$values = ['foo', '', 'bar', '0', 'baz', 0, 'qux', null, 'quz', false, 'impossible'];
$calls = 0;
$stmt = $this->createMock(Statement::class);
$stmt->expects($this->exactly(10))
->method('fetch')
->willReturnCallback(function() use ($values, &$calls) {
$value = $values[$calls];
$calls++;
return $value;
});
$stmtIterator = new StatementIterator($stmt);
foreach ($stmtIterator as $i => $_) {
$this->assertEquals($i + 1, $calls);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment