Skip to content

Commit

Permalink
Merge pull request #3 from vemaeg/feature/low-memory-on-demand
Browse files Browse the repository at this point in the history
The OnDemand Hydrator builds the objects by each iteration, but stores…
  • Loading branch information
thirsch authored Dec 15, 2022
2 parents 92abb24 + 92c332b commit 7d448d9
Showing 1 changed file with 52 additions and 0 deletions.
52 changes: 52 additions & 0 deletions lib/Doctrine/Collection/OnDemand.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class Doctrine_Collection_OnDemand implements Iterator
protected $_current;
protected $_tableAliasMap;
protected $_hydrator;
protected $_lowMemory;
protected $index;

public function __construct($stmt, $hydrator, $tableAliasMap)
Expand All @@ -45,11 +46,22 @@ public function __construct($stmt, $hydrator, $tableAliasMap)
$this->_hydrator = $hydrator;
$this->_tableAliasMap = $tableAliasMap;
$this->_current = null;
$this->_lowMemory = false;
$this->index = 0;

$this->_hydrateCurrent();
}

public function setLowMemory($lowMemory)
{
$this->_lowMemory = $lowMemory;
}

public function close()
{
$this->_stmt->closeCursor();
}

private function _hydrateCurrent()
{
$record = $this->_hydrator->hydrateResultSet($this->_stmt);
Expand Down Expand Up @@ -89,6 +101,46 @@ public function current()
#[\ReturnTypeWillChange]
public function next()
{
if ($this->_lowMemory && !is_null($this->_current)) {
$this->_hydrator->flush();

$models = [$this->_current];
$cleanedModels = [];

while (count($models)) {
/** @var Doctrine_Record $model */
$model = array_shift($models);

// Empty value or Doctrine_Null: Nothing to do...
// This could be the case, if a foreign key relation does not
// contain a value and Doctrine has put a Doctrine_Null as a
// placeholder and we merged it to the models list below.
if (!$model || $model instanceof Doctrine_Null) {
continue;
}

// Has this model already be removed in this cycle? Skip it!
if (in_array($model, $cleanedModels)) {
continue;
}

if ($model instanceof Doctrine_Collection) {
// Pushe alle Elemente der Collection in die aufzuräumenden Models.
$models = array_merge($models, $model->getData());
} else {
// Pushe alle referenzierten Modelle in die aufzuräumenden Models.
$models = array_merge($models, $model->getReferences());

/** @var Doctrine_Table $table */
$table = $model->getTable();
$table->removeRecord($model);
$table->getRepository()->evict($model->getOID());

array_push($cleanedModels, $model);
}
}
}

$this->_current = null;
$this->index++;
$this->_hydrateCurrent();
Expand Down

0 comments on commit 7d448d9

Please sign in to comment.