performance tuning on timesheets (#874)

This commit is contained in:
Kevin Papst
2019-06-20 16:05:31 +02:00
committed by GitHub
parent bb8572a364
commit 9fbbaf9b88
11 changed files with 290 additions and 50 deletions

View File

@@ -16,13 +16,16 @@ use App\Model\Statistic\Day;
use App\Model\Statistic\Month;
use App\Model\Statistic\Year;
use App\Model\TimesheetStatistic;
use App\Repository\Loader\TimesheetLoader;
use App\Repository\Paginator\TimesheetPaginator;
use App\Repository\Query\TimesheetQuery;
use DateTime;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Pagerfanta;
class TimesheetRepository extends AbstractRepository
class TimesheetRepository extends EntityRepository
{
public const STATS_QUERY_DURATION = 'duration';
public const STATS_QUERY_RATE = 'rate';
@@ -352,7 +355,7 @@ class TimesheetRepository extends AbstractRepository
->join('t.project', 'p')
->join('p.customer', 'c')
->leftJoin('t.tags', 'tags')
->where($qb->expr()->isNotNull('t.begin'))
->andWhere($qb->expr()->isNotNull('t.begin'))
->andWhere($qb->expr()->isNull('t.end'))
->orderBy('t.begin', 'DESC');
@@ -402,22 +405,45 @@ class TimesheetRepository extends AbstractRepository
return $counter;
}
public function getPagerfantaForQuery(TimesheetQuery $query): Pagerfanta
{
$paginator = new Pagerfanta($this->getPaginatorForQuery($query));
$paginator->setMaxPerPage($query->getPageSize());
$paginator->setCurrentPage($query->getPage());
return $paginator;
}
protected function getPaginatorForQuery(TimesheetQuery $query): TimesheetPaginator
{
$qb = $this->getQueryBuilderForQuery($query);
$qb->select($qb->expr()->countDistinct('t.id'))->resetDQLPart('orderBy');
$counter = (int) $qb->getQuery()->getSingleScalarResult();
$qb = $this->getQueryBuilderForQuery($query);
$qb->select('t');
$paginator = new TimesheetPaginator($qb, $counter);
return $paginator;
}
/**
* @param TimesheetQuery $query
* @return QueryBuilder|Pagerfanta|array
* @return Timesheet[]
*/
public function findByQuery(TimesheetQuery $query)
public function getTimesheetsForQuery(TimesheetQuery $query): array
{
$paginator = $this->getPaginatorForQuery($query);
return $paginator->getAll();
}
protected function getQueryBuilderForQuery(TimesheetQuery $query): QueryBuilder
{
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('t', 'a', 'p', 'c', 'u', 'tags')
->from(Timesheet::class, 't')
->leftJoin('t.activity', 'a')
->leftJoin('t.user', 'u')
->leftJoin('t.project', 'p')
->leftJoin('p.customer', 'c')
->leftJoin('t.tags', 'tags')
->orderBy('t.' . $query->getOrderBy(), $query->getOrder());
$qb->from(Timesheet::class, 't');
if (null !== $query->getUser()) {
$qb->andWhere('t.user = :user')
@@ -456,6 +482,7 @@ class TimesheetRepository extends AbstractRepository
$qb->andWhere('t.project = :project')
->setParameter('project', $query->getProject());
} elseif (null !== $query->getCustomer()) {
$qb->join('t.project', 'p');
$qb->andWhere('p.customer = :customer')
->setParameter('customer', $query->getCustomer());
}
@@ -467,7 +494,9 @@ class TimesheetRepository extends AbstractRepository
->setParameter('tags', $query->getTags());
}
return $this->getBaseQueryResult($qb, $query);
$qb->orderBy('t.' . $query->getOrderBy(), $query->getOrder());
return $qb;
}
/**
@@ -516,16 +545,17 @@ class TimesheetRepository extends AbstractRepository
$ids = array_column($results, 'maxid');
$qb = $this->getEntityManager()->createQueryBuilder();
$qb->select('t', 'a', 'p', 'c', 'tags')
$qb->select('t')
->from(Timesheet::class, 't')
->join('t.activity', 'a')
->join('t.project', 'p')
->join('p.customer', 'c')
->leftJoin('t.tags', 'tags')
->andWhere($qb->expr()->in('t.id', $ids))
->orderBy('t.end', 'DESC')
;
return $qb->getQuery()->getResult();
$results = $qb->getQuery()->getResult();
$loader = new TimesheetLoader($qb->getEntityManager());
$loader->loadResults($results);
return $results;
}
}