Commit 078d32ea authored by Ian Jenkins's avatar Ian Jenkins

Extract statement iterator into own class

parent 22b2b6b6
......@@ -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()
{
while ($row = $this->fetch()) {
yield $row;
}
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()
{
while ($row = $this->fetch()) {
yield $row;
}
return new StatementIterator($this);
}
}
......@@ -37,7 +37,7 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
/**
* @var integer
*/
protected $executeMode;
protected $executeMode = OCI_COMMIT_ON_SUCCESS;
/**
* Creates a Connection to an Oracle Database using oci8 extension.
......@@ -57,8 +57,6 @@ class OCI8Connection implements Connection, ServerInfoAwareConnection
define('OCI_NO_AUTO_COMMIT', 0);
}
$this->executeMode = OCI_COMMIT_ON_SUCCESS;
$this->dbh = $persistent
? @oci_pconnect($username, $password, $db, $charset, $sessionMode)
: @oci_connect($username, $password, $db, $charset, $sessionMode);
......
......@@ -20,7 +20,8 @@
namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\Statement;
use \IteratorAggregate;
use Doctrine\DBAL\Driver\StatementIterator;
use IteratorAggregate;
use PDO;
/**
......@@ -370,9 +371,7 @@ class OCI8Statement implements IteratorAggregate, Statement
*/
public function getIterator()
{
while ($row = $this->fetch()) {
yield $row;
}
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,9 +279,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
*/
public function getIterator()
{
while ($row = $this->fetch()) {
yield $row;
}
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()
{
while ($row = $this->fetch()) {
yield $row;
}
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);
}
}
}
......@@ -3,19 +3,8 @@
namespace Doctrine\Tests\DBAL\Functional;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\IBMDB2\DB2Connection;
use Doctrine\DBAL\Driver\IBMDB2\DB2Statement;
use Doctrine\DBAL\Driver\Mysqli\MysqliConnection;
use Doctrine\DBAL\Driver\Mysqli\MysqliStatement;
use Doctrine\DBAL\Driver\OCI8\OCI8Connection;
use Doctrine\DBAL\Driver\OCI8\OCI8Statement;
use Doctrine\DBAL\Driver\SQLAnywhere\SQLAnywhereConnection;
use Doctrine\DBAL\Driver\SQLAnywhere\SQLAnywhereStatement;
use Doctrine\DBAL\Driver\SQLSrv\SQLSrvConnection;
use Doctrine\DBAL\Driver\SQLSrv\SQLSrvStatement;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\Type;
use IteratorIterator;
use PDO;
class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase
......@@ -877,55 +866,9 @@ class DataAccessTest extends \Doctrine\Tests\DbalFunctionalTestCase
$this->markTestSkipped('Mysqli driver dont support this feature.');
}
}
}
public function getConnections()
{
return [
[MysqliConnection::class, MysqliStatement::class],
[OCI8Connection::class, OCI8Statement::class],
[DB2Connection::class, DB2Statement::class],
[SQLAnywhereConnection::class, SQLAnywhereStatement::class],
[SQLSrvConnection::class, SQLSrvStatement::class],
];
}
/**
* @dataProvider getConnections
*/
public function testGettingIteratorDoesNotCallFetch($connection, $statement)
{
$stmt = $this->createPartialMock($statement, ['fetch']);
$stmt->expects($this->never())->method('fetch');
$conn = $this->createMock($connection);
$conn->expects($this->any())->method('prepare')->willReturn($stmt);
$ii = new IteratorIterator($stmt);
$ii->getInnerIterator();
}
/**
* @dataProvider getConnections
*/
public function testIterationCallsFetchOncePerStep($connection, $statement)
{
$values = ['foo', '', 'bar', '0', 'baz', 0, 'qux', null, 'quz', false];
$calls = 0;
$stmt = $this->createPartialMock($statement, ['fetch']);
$stmt->expects($this->exactly(10))
->method('fetch')
->willReturnCallback(function() use ($values, &$calls) {
$calls++;
yield from $values;
});
$conn = $this->createMock($connection);
$conn->expects($this->any())->method('prepare')->willReturn($stmt);
foreach ($stmt as $i => $_) {
$_->next();
$this->assertEquals($i + 1, $calls);
}
}
class MyFetchClass
{
public $test_int, $test_string, $test_datetime;
}
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