Skip to content

Commit

Permalink
Replaced ArrayIterator with StatementIterator in Portability\Connection
Browse files Browse the repository at this point in the history
  • Loading branch information
morozov committed Apr 22, 2018
1 parent 5ba43cf commit 8216edf
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 10 deletions.
5 changes: 2 additions & 3 deletions lib/Doctrine/DBAL/Portability/Statement.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

namespace Doctrine\DBAL\Portability;

use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\FetchMode;
use Doctrine\DBAL\ParameterType;
use function array_change_key_case;
Expand Down Expand Up @@ -139,9 +140,7 @@ public function setFetchMode($fetchMode, $arg1 = null, $arg2 = null)
*/
public function getIterator()
{
$data = $this->fetchAll();

return new \ArrayIterator($data);
return new StatementIterator($this);
}

/**
Expand Down
66 changes: 59 additions & 7 deletions tests/Doctrine/Tests/DBAL/Driver/StatementIteratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,39 +2,91 @@

namespace Doctrine\Tests\DBAL\Driver;

use Doctrine\DBAL\Driver\IBMDB2\DB2Statement;
use Doctrine\DBAL\Driver\Mysqli\MysqliStatement;
use Doctrine\DBAL\Driver\OCI8\OCI8Statement;
use Doctrine\DBAL\Driver\SQLAnywhere\SQLAnywhereStatement;
use Doctrine\DBAL\Driver\SQLSrv\SQLSrvStatement;
use Doctrine\DBAL\Driver\Statement;
use Doctrine\DBAL\Driver\StatementIterator;
use Doctrine\DBAL\Portability\Statement as PortabilityStatement;
use PHPUnit\Framework\MockObject\MockObject;
use function extension_loaded;

class StatementIteratorTest extends \Doctrine\Tests\DbalTestCase
{
public function testGettingIteratorDoesNotCallFetch()
/**
* @dataProvider statementProvider()
*/
public function testGettingIteratorDoesNotCallFetch(string $class)
{
$stmt = $this->createMock(Statement::class);
$stmt = $this->createPartialMock($class, ['fetch', 'fetchAll', 'fetchColumn']);
$stmt->expects($this->never())->method('fetch');
$stmt->expects($this->never())->method('fetchAll');
$stmt->expects($this->never())->method('fetchColumn');

$stmt->getIterator();
}

public function testIteratorIterationCallsFetchOncePerStep()
{
$stmt = $this->createMock(Statement::class);
$this->configureStatement($stmt, $calls);

$stmtIterator = new StatementIterator($stmt);
$stmtIterator->getIterator();

$this->assertIterationCallsFetchOncePerStep($stmtIterator, $calls);
}

public function testIterationCallsFetchOncePerStep()
/**
* @dataProvider statementProvider()
*/
public function testStatementIterationCallsFetchOncePerStep(string $class)
{
$stmt = $this->createPartialMock($class, ['fetch']);
$this->configureStatement($stmt, $calls);
$this->assertIterationCallsFetchOncePerStep($stmt, $calls);
}

private function configureStatement(MockObject $stmt, &$calls) : void
{
$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 => $_) {
private function assertIterationCallsFetchOncePerStep($iterator, &$calls) : void
{
foreach ($iterator as $i => $_) {
$this->assertEquals($i + 1, $calls);
}
}

public static function statementProvider()
{
if (extension_loaded('ibm_db2')) {
yield [DB2Statement::class];
}

yield [MysqliStatement::class];

if (extension_loaded('oci8')) {
yield [OCI8Statement::class];
}

yield [PortabilityStatement::class];
yield [SQLAnywhereStatement::class];

if (extension_loaded('sqlsrv')) {
yield [SQLSrvStatement::class];
}
}
}

0 comments on commit 8216edf

Please sign in to comment.