Updated VisitRepository::findUnlocatedVisits methods so that it paginates the amount of elements loaded in memory

This commit is contained in:
Alejandro Celaya
2019-02-22 19:31:03 +01:00
parent 08bd4f131c
commit 292937b962
7 changed files with 115 additions and 11 deletions

View File

@@ -5,17 +5,32 @@ namespace Shlinkio\Shlink\Core\Repository;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Shlinkio\Shlink\Common\Paginator\Adapter\PaginableQueryAdapter;
use Shlinkio\Shlink\Common\Paginator\ImplicitLoopPaginator;
use Shlinkio\Shlink\Common\Util\DateRange;
use Shlinkio\Shlink\Core\Entity\Visit;
use Zend\Paginator\Paginator;
use function array_shift;
class VisitRepository extends EntityRepository implements VisitRepositoryInterface
{
public function findUnlocatedVisits(): iterable
/**
* @return iterable|Visit[]
*/
public function findUnlocatedVisits(int $blockSize = self::DEFAULT_BLOCK_SIZE): iterable
{
$dql = 'SELECT v FROM Shlinkio\Shlink\Core\Entity\Visit AS v WHERE v.visitLocation IS NULL';
$count = $this->count(['visitLocation' => null]);
$dql = <<<DQL
SELECT v FROM Shlinkio\Shlink\Core\Entity\Visit AS v WHERE v.visitLocation IS NULL
DQL;
$query = $this->getEntityManager()->createQuery($dql);
return $query->iterate();
$paginator = new Paginator(new PaginableQueryAdapter($query, $count));
$paginator->setItemCountPerPage($blockSize);
return new ImplicitLoopPaginator($paginator, function (array $value) {
return array_shift($value);
});
}
/**

View File

@@ -9,7 +9,12 @@ use Shlinkio\Shlink\Core\Entity\Visit;
interface VisitRepositoryInterface extends ObjectRepository
{
public function findUnlocatedVisits(): iterable;
public const DEFAULT_BLOCK_SIZE = 10000;
/**
* @return iterable|Visit[]
*/
public function findUnlocatedVisits(int $blockSize = self::DEFAULT_BLOCK_SIZE): iterable;
/**
* @return Visit[]

View File

@@ -26,7 +26,7 @@ class VisitService implements VisitServiceInterface
$repo = $this->em->getRepository(Visit::class);
$results = $repo->findUnlocatedVisits();
foreach ($results as [$visit]) {
foreach ($results as $visit) {
try {
/** @var Location $location */
$location = $geolocateVisit($visit);