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:
parent
29df80b48f
commit
7aa12f192a
2 changed files with 43 additions and 0 deletions
|
@ -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(
|
||||
|
|
41
src/infrastructure/storage/lisk/PhabricatorQueryIterator.php
Normal file
41
src/infrastructure/storage/lisk/PhabricatorQueryIterator.php
Normal 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;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue