1
0
Fork 0
mirror of https://we.phorge.it/source/phorge.git synced 2025-01-11 07:11:04 +01:00

Add PhabricatorQueryIterator, for buffered iteration over a CursorPagedPolicyAwareQuery

Summary:
See D19446. This should make it easier to process larger, more complex result sets in constant memory.

Today, `LiskMigrationIterator` takes constant memory but can't apply `needX()` reqeusts or `withY(...)` constraints.

Using a raw `Query` can handle this stuff, but requires memory proportional to the size of the result set.

Offer the best of both worlds: constant memory and full access to the power of `Query` classes.

Test Plan:
Used this script to iterate over every commit, saw sensible behavior:

```name=list-commits.php
<?php

require_once 'scripts/init/init-script.php';

$viewer = PhabricatorUser::getOmnipotentUser();

$query = id(new DiffusionCommitQuery())
  ->setViewer($viewer);

$iterator = new PhabricatorQueryIterator($query);
foreach ($iterator as $commit) {
  echo $commit->getID()."\n";
}
```

Reviewers: amckinley

Reviewed By: amckinley

Differential Revision: https://secure.phabricator.com/D19450
This commit is contained in:
epriestley 2018-05-14 09:16:09 -07:00
parent 29df80b48f
commit 7aa12f192a
2 changed files with 43 additions and 0 deletions

View file

@ -4032,6 +4032,7 @@ phutil_register_library_map(array(
'PhabricatorPygmentSetupCheck' => 'applications/config/check/PhabricatorPygmentSetupCheck.php',
'PhabricatorQuery' => 'infrastructure/query/PhabricatorQuery.php',
'PhabricatorQueryConstraint' => 'infrastructure/query/constraint/PhabricatorQueryConstraint.php',
'PhabricatorQueryIterator' => 'infrastructure/storage/lisk/PhabricatorQueryIterator.php',
'PhabricatorQueryOrderItem' => 'infrastructure/query/order/PhabricatorQueryOrderItem.php',
'PhabricatorQueryOrderTestCase' => 'infrastructure/query/order/__tests__/PhabricatorQueryOrderTestCase.php',
'PhabricatorQueryOrderVector' => 'infrastructure/query/order/PhabricatorQueryOrderVector.php',
@ -9876,6 +9877,7 @@ phutil_register_library_map(array(
'PhabricatorPygmentSetupCheck' => 'PhabricatorSetupCheck',
'PhabricatorQuery' => 'Phobject',
'PhabricatorQueryConstraint' => 'Phobject',
'PhabricatorQueryIterator' => 'PhutilBufferedIterator',
'PhabricatorQueryOrderItem' => 'Phobject',
'PhabricatorQueryOrderTestCase' => 'PhabricatorTestCase',
'PhabricatorQueryOrderVector' => array(

View file

@ -0,0 +1,41 @@
<?php
final class PhabricatorQueryIterator extends PhutilBufferedIterator {
private $query;
private $pager;
public function __construct(PhabricatorCursorPagedPolicyAwareQuery $query) {
$this->query = $query;
}
protected function didRewind() {
$this->pager = new AphrontCursorPagerView();
}
public function key() {
return $this->current()->getID();
}
protected function loadPage() {
if (!$this->pager) {
return array();
}
$pager = clone $this->pager;
$query = clone $this->query;
$results = $query->executeWithCursorPager($pager);
// If we got less than a full page of results, this was the last set of
// results. Throw away the pager so we end iteration.
if (count($results) < $pager->getPageSize()) {
$this->pager = null;
} else {
$this->pager->setAfterID($pager->getNextPageID());
}
return $results;
}
}