Commit 55b672f4 authored by Ian Jenkins's avatar Ian Jenkins

Add iterators for non pdo drivers.

Allows result sets to be iterated over without running out of memory on
large data sets.
parent 373ae9ed
<?php
namespace Doctrine\DBAL\Driver;
abstract class AbstractIterator
{
protected $cursor;
protected $key;
protected $current;
protected $fetched = 0;
protected $defaultFetchMode;
public function __construct($cursor, $defaultFetchMode = \PDO::FETCH_BOTH)
{
$this->cursor = $cursor;
$this->defaultFetchMode = $defaultFetchMode;
$this->next();
}
public function current()
{
return $this->current;
}
public function next()
{
$this->key = $this->fetched;
$this->current = $this->fetch();
if ($this->current) {
$this->fetched++;
}
}
public function key()
{
return $this->key;
}
public function valid()
{
return (bool)$this->current;
}
public function rewind()
{
// Not supported
}
abstract protected function fetch();
}
<?php
namespace Doctrine\DBAL\Driver\IBMDB2;
use Doctrine\DBAL\Driver\AbstractIterator;
class DB2Iterator extends AbstractIterator implements \Iterator
{
protected function fetch()
{
switch ($this->defaultFetchMode) {
case \PDO::FETCH_BOTH:
return db2_fetch_both($this->cursor);
case \PDO::FETCH_ASSOC:
return db2_fetch_assoc($this->cursor);
case \PDO::FETCH_CLASS:
return db2_fetch_object($this->cursor);
case \PDO::FETCH_NUM:
return db2_fetch_array($this->cursor);
case \PDO::FETCH_OBJ:
return db2_fetch_object($this->cursor);
default:
throw new DB2Exception("Given Fetch-Style " . $this->defaultFetchMode . " is not supported.");
}
}
}
...@@ -199,9 +199,7 @@ class DB2Statement implements \IteratorAggregate, Statement ...@@ -199,9 +199,7 @@ class DB2Statement implements \IteratorAggregate, Statement
*/ */
public function getIterator() public function getIterator()
{ {
$data = $this->fetchAll(); return new DB2Iterator($this->_stmt, $this->_defaultFetchMode);
return new \ArrayIterator($data);
} }
/** /**
......
<?php
namespace Doctrine\DBAL\Driver\Mysqli;
use Doctrine\DBAL\Driver\AbstractIterator;
class MysqliIterator extends AbstractIterator implements \Iterator
{
protected function fetch()
{
switch ($this->defaultFetchMode) {
case \PDO::FETCH_COLUMN:
return $this->fetchColumn();
default:
return $this->fetch($this->defaultFetchMode);
}
}
}
...@@ -406,8 +406,6 @@ class MysqliStatement implements \IteratorAggregate, Statement ...@@ -406,8 +406,6 @@ class MysqliStatement implements \IteratorAggregate, Statement
*/ */
public function getIterator() public function getIterator()
{ {
$data = $this->fetchAll(); return new MysqliIterator($this->_stmt, $this->_defaultFetchMode);
return new \ArrayIterator($data);
} }
} }
<?php
namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\AbstractIterator;
class OCI8Iterator extends AbstractIterator implements \Iterator
{
private static $fetchModeMap = array(
\PDO::FETCH_BOTH => OCI_BOTH,
\PDO::FETCH_ASSOC => OCI_ASSOC,
\PDO::FETCH_NUM => OCI_NUM,
\PDO::FETCH_COLUMN => OCI_NUM,
);
protected function fetch()
{
$result = [];
if (\PDO::FETCH_OBJ === $this->defaultFetchMode) {
return oci_fetch_object($this->cursor);
}
if (self::$fetchModeMap[$this->defaultFetchMode] === OCI_BOTH) {
return oci_fetch_array(
$this->cursor,
$this->defaultFetchMode | OCI_RETURN_NULLS | OCI_RETURN_LOBS
);
}
$fetchStructure = OCI_FETCHSTATEMENT_BY_ROW;
if ($this->defaultFetchMode === \PDO::FETCH_COLUMN) {
$fetchStructure = OCI_FETCHSTATEMENT_BY_COLUMN;
}
oci_fetch_all(
$this->cursor,
$result,
0,
-1,
self::$fetchModeMap[$this->defaultFetchMode] | OCI_RETURN_NULLS | $fetchStructure | OCI_RETURN_LOBS
);
return $result;
}
}
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
namespace Doctrine\DBAL\Driver\OCI8; namespace Doctrine\DBAL\Driver\OCI8;
use Doctrine\DBAL\Driver\Statement; use Doctrine\DBAL\Driver\Statement;
use \IteratorAggregate;
use PDO; use PDO;
/** /**
...@@ -28,7 +29,7 @@ use PDO; ...@@ -28,7 +29,7 @@ use PDO;
* @since 2.0 * @since 2.0
* @author Roman Borschel <roman@code-factory.org> * @author Roman Borschel <roman@code-factory.org>
*/ */
class OCI8Statement implements \IteratorAggregate, Statement class OCI8Statement implements IteratorAggregate, Statement
{ {
/** /**
* @var resource * @var resource
...@@ -369,9 +370,7 @@ class OCI8Statement implements \IteratorAggregate, Statement ...@@ -369,9 +370,7 @@ class OCI8Statement implements \IteratorAggregate, Statement
*/ */
public function getIterator() public function getIterator()
{ {
$data = $this->fetchAll(); return new OCI8Iterator($this->_sth, $this->_defaultFetchMode);
return new \ArrayIterator($data);
} }
/** /**
......
<?php
namespace Doctrine\DBAL\Driver\SQLAnywhere;
use Doctrine\DBAL\Driver\AbstractIterator;
class SQLAnywhereIterator extends AbstractIterator implements \Iterator
{
protected function fetch()
{
$result = sasql_stmt_result_metadata($this->cursor);
switch ($this->defaultFetchMode) {
case \PDO::FETCH_ASSOC:
return sasql_fetch_assoc($this->cursor);
case \PDO::FETCH_BOTH:
return sasql_fetch_array($result, SASQL_BOTH);
case \PDO::FETCH_CLASS:
return sasql_fetch_object($result);
case \PDO::FETCH_NUM:
return sasql_fetch_row($result);
case \PDO::FETCH_OBJ:
return sasql_fetch_object($result);
default:
throw new SQLAnywhereException('Fetch mode is not supported: ' . $this->defaultFetchMode);
}
}
}
...@@ -278,7 +278,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement ...@@ -278,7 +278,7 @@ class SQLAnywhereStatement implements IteratorAggregate, Statement
*/ */
public function getIterator() public function getIterator()
{ {
return new \ArrayIterator($this->fetchAll()); return new SQLAnywhereIterator($this->stmt, $this->defaultFetchMode);
} }
/** /**
......
<?php
namespace Doctrine\DBAL\Driver\SQLSrv;
use Doctrine\DBAL\Driver\AbstractIterator;
class SQLSrvIterator extends AbstractIterator implements \Iterator
{
protected function fetch()
{
return sqlsrv_fetch_array($this->cursor, $this->defaultFetchMode);
}
}
...@@ -295,9 +295,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement ...@@ -295,9 +295,7 @@ class SQLSrvStatement implements IteratorAggregate, Statement
*/ */
public function getIterator() public function getIterator()
{ {
$data = $this->fetchAll(); return new SQLSrvIterator($this->stmt, $this->defaultFetchMode);
return new \ArrayIterator($data);
} }
/** /**
......
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