Skip to content

Commit

Permalink
Use same query for RSS & dashboard
Browse files Browse the repository at this point in the history
Instead of grouping repo to display only the latest release on the dashboard, use the same query for the RSS which will display all latest releases non-grouping per repo.
This speedup the query and the dashboard display.

Going from 2s to 55ms
  • Loading branch information
j0k3r committed Apr 1, 2017
1 parent 4aabc1d commit 0bf413e
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 51 deletions.
4 changes: 2 additions & 2 deletions src/AppBundle/Controller/DefaultController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,12 @@ public function dashboardAction(Request $request)

// Pass the item total
$paginator->setItemTotalCallback(function () use ($repoVersion, $userId) {
return $repoVersion->countLastVersionForEachRepoForUser($userId);
return $repoVersion->countForUser($userId);
});

// Pass the slice
$paginator->setSliceCallback(function ($offset, $length) use ($repoVersion, $userId) {
return $repoVersion->findLastVersionForEachRepoForUser($userId, $offset, $length);
return $repoVersion->findForUser($userId, $offset, $length);
});

// Paginate using the current page number
Expand Down
62 changes: 14 additions & 48 deletions src/AppBundle/Repository/VersionRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,58 +39,41 @@ public function findExistingOne($tagName, $repoId)

/**
* Find all versions available for the given user.
* They'll be put in a RSS feed.
*
* @param int $userId
*
* @return array
*/
public function findForUser($userId)
public function findForUser($userId, $offset = 0, $length = 20)
{
return $this->createQueryBuilder('v')
->select('v.tagName', 'v.createdAt', 'v.body', 'r.fullName', 'r.ownerAvatar', 'r.ownerAvatar', 'r.homepage', 'r.language', 'r.description')
->select('v.tagName', 'v.name', 'v.createdAt', 'v.body', 'v.prerelease', 'r.fullName', 'r.ownerAvatar', 'r.ownerAvatar', 'r.homepage', 'r.language', 'r.description')
->leftJoin('v.repo', 'r')
->leftJoin('r.stars', 's')
->where('s.user = :userId')->setParameter('userId', $userId)
->orderBy('v.createdAt', 'desc')
->setMaxResults(20)
->getQuery()
->getArrayResult();
}

/**
* Retrieve latest version of each repo for a user_id with pagination.
*
* @param int $userId User ID
* @param int $offset
* @param int $length
*
* @return array
*/
public function findLastVersionForEachRepoForUser($userId, $offset = 0, $length = 30)
{
$query = 'SELECT v1.tagName, v1.name, v1.createdAt, r.fullName, r.description, r.ownerAvatar, v1.prerelease ' . $this->getBaseQueryForLastVersionForEachRepoForUser();

return $this->getEntityManager()->createQuery($query)
->setFirstResult($offset)
->setMaxResults($length)
->setParameter('userId', $userId)
->getQuery()
->getArrayResult();
}

/**
* Return total lines for latest version of each repo for a user_id with pagination.
* Count all versions available for the given user.
* Used in the dashboard pagination.
*
* @param int $userId User ID
* @param int $userId
*
* @return int
* @return array
*/
public function countLastVersionForEachRepoForUser($userId)
public function countForUser($userId)
{
$query = 'SELECT count(v1.id) ' . $this->getBaseQueryForLastVersionForEachRepoForUser();

return (int) $this->getEntityManager()->createQuery($query)
->setParameter('userId', $userId)
return $this->createQueryBuilder('v')
->select('COUNT(v.id)')
->leftJoin('v.repo', 'r')
->leftJoin('r.stars', 's')
->where('s.user = :userId')->setParameter('userId', $userId)
->getQuery()
->getSingleScalarResult();
}

Expand Down Expand Up @@ -130,21 +113,4 @@ public function count()
->getQuery()
->getSingleScalarResult();
}

/**
* DQL query to retrieve last version of each repo starred by a user (or globally).
* We use DQL because it was to complex to use a query builder.
*
* @return string
*/
private function getBaseQueryForLastVersionForEachRepoForUser()
{
return 'FROM AppBundle\Entity\Version v1
LEFT JOIN AppBundle\Entity\Version v2 WITH (v1.repo = v2.repo AND v1.createdAt < v2.createdAt)
LEFT JOIN AppBundle\Entity\Star s WITH s.repo = v1.repo
LEFT JOIN AppBundle\Entity\Repo r WITH r.id = s.repo
WHERE v2.repo IS NULL
AND s.user = :userId
ORDER BY v1.createdAt DESC';
}
}
2 changes: 1 addition & 1 deletion src/AppBundle/Security/GithubAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function onAuthenticationFailure(Request $request, AuthenticationExceptio

public function onAuthenticationSuccess(Request $request, TokenInterface $token, $providerKey)
{
$versions = $this->em->getRepository('AppBundle:Version')->findLastVersionForEachRepoForUser($token->getUser()->getId());
$versions = $this->em->getRepository('AppBundle:Version')->findForUser($token->getUser()->getId());

// if no versions were found, it means the user logged in for the first time
// and we need to display an explanation message
Expand Down

0 comments on commit 0bf413e

Please sign in to comment.