From 2030401859e36bfb55b8d6b0b2b6ee045031147a Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 19 Dec 2018 14:29:43 +0100 Subject: [PATCH 1/4] Migrated non-dynamic query to DQL in ShortUrlRepository --- .../src/Repository/ShortUrlRepository.php | 56 ++++++------------- .../ShortUrlRepositoryInterface.php | 6 +- 2 files changed, 19 insertions(+), 43 deletions(-) diff --git a/module/Core/src/Repository/ShortUrlRepository.php b/module/Core/src/Repository/ShortUrlRepository.php index b204d6f8..5d505fa4 100644 --- a/module/Core/src/Repository/ShortUrlRepository.php +++ b/module/Core/src/Repository/ShortUrlRepository.php @@ -16,12 +16,9 @@ use function key; class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryInterface { /** - * @param int|null $limit - * @param int|null $offset - * @param string|null $searchTerm - * @param array $tags + * @param string[] $tags * @param string|array|null $orderBy - * @return \Shlinkio\Shlink\Core\Entity\ShortUrl[] + * @return ShortUrl[] */ public function findList( int $limit = null, @@ -51,7 +48,7 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI return $qb->getQuery()->getResult(); } - protected function processOrderByForList(QueryBuilder $qb, $orderBy) + private function processOrderByForList(QueryBuilder $qb, $orderBy): array { // Map public field names to column names $fieldNameMap = [ @@ -78,13 +75,6 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI return $qb->getQuery()->getResult(); } - /** - * Counts the number of elements in a list using provided filtering data - * - * @param null|string $searchTerm - * @param array $tags - * @return int - */ public function countList(string $searchTerm = null, array $tags = []): int { $qb = $this->createListQueryBuilder($searchTerm, $tags); @@ -93,12 +83,7 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI return (int) $qb->getQuery()->getSingleScalarResult(); } - /** - * @param null|string $searchTerm - * @param array $tags - * @return QueryBuilder - */ - protected function createListQueryBuilder(string $searchTerm = null, array $tags = []): QueryBuilder + private function createListQueryBuilder(?string $searchTerm = null, array $tags = []): QueryBuilder { $qb = $this->getEntityManager()->createQueryBuilder(); $qb->from(ShortUrl::class, 's'); @@ -131,30 +116,25 @@ class ShortUrlRepository extends EntityRepository implements ShortUrlRepositoryI return $qb; } - /** - * @param string $shortCode - * @return ShortUrl|null - */ public function findOneByShortCode(string $shortCode): ?ShortUrl { - $now = Chronos::now(); + $dql= <<= :now OR s.validUntil IS NULL) +DQL; - $qb = $this->createQueryBuilder('s'); - $qb->where($qb->expr()->eq('s.shortCode', ':shortCode')) - ->setParameter('shortCode', $shortCode) - ->andWhere($qb->expr()->orX( - $qb->expr()->lte('s.validSince', ':now'), - $qb->expr()->isNull('s.validSince') - )) - ->andWhere($qb->expr()->orX( - $qb->expr()->gte('s.validUntil', ':now'), - $qb->expr()->isNull('s.validUntil') - )) - ->setParameter('now', $now) - ->setMaxResults(1); + $query = $this->getEntityManager()->createQuery($dql); + $query->setMaxResults(1) + ->setParameters([ + 'shortCode' => $shortCode, + 'now' => Chronos::now(), + ]); /** @var ShortUrl|null $result */ - $result = $qb->getQuery()->getOneOrNullResult(); + $result = $query->getOneOrNullResult(); return $result === null || $result->maxVisitsReached() ? null : $result; } } diff --git a/module/Core/src/Repository/ShortUrlRepositoryInterface.php b/module/Core/src/Repository/ShortUrlRepositoryInterface.php index bff0d723..b1edab1b 100644 --- a/module/Core/src/Repository/ShortUrlRepositoryInterface.php +++ b/module/Core/src/Repository/ShortUrlRepositoryInterface.php @@ -9,9 +9,5 @@ use Shlinkio\Shlink\Core\Entity\ShortUrl; interface ShortUrlRepositoryInterface extends ObjectRepository, PaginableRepositoryInterface { - /** - * @param string $shortCode - * @return ShortUrl|null - */ - public function findOneByShortCode(string $shortCode); + public function findOneByShortCode(string $shortCode): ?ShortUrl; } From f8207994dc62ba46e5c8ffbb854464f3bee6ac18 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 19 Dec 2018 14:31:52 +0100 Subject: [PATCH 2/4] Removed superfluous method docs --- module/Core/src/Repository/TagRepository.php | 6 ------ module/Core/src/Repository/TagRepositoryInterface.php | 6 ------ 2 files changed, 12 deletions(-) diff --git a/module/Core/src/Repository/TagRepository.php b/module/Core/src/Repository/TagRepository.php index dec1d8e9..3ccb7ac5 100644 --- a/module/Core/src/Repository/TagRepository.php +++ b/module/Core/src/Repository/TagRepository.php @@ -8,12 +8,6 @@ use Shlinkio\Shlink\Core\Entity\Tag; class TagRepository extends EntityRepository implements TagRepositoryInterface { - /** - * Delete the tags identified by provided names - * - * @param array $names - * @return int The number of affected entries - */ public function deleteByName(array $names): int { if (empty($names)) { diff --git a/module/Core/src/Repository/TagRepositoryInterface.php b/module/Core/src/Repository/TagRepositoryInterface.php index 0fa45cc3..d482fdd0 100644 --- a/module/Core/src/Repository/TagRepositoryInterface.php +++ b/module/Core/src/Repository/TagRepositoryInterface.php @@ -7,11 +7,5 @@ use Doctrine\Common\Persistence\ObjectRepository; interface TagRepositoryInterface extends ObjectRepository { - /** - * Delete the tags identified by provided names - * - * @param array $names - * @return int The number of affected entries - */ public function deleteByName(array $names): int; } From 58dbee10c52a6538b5d37c7d5cb71b30b6464111 Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 19 Dec 2018 14:36:03 +0100 Subject: [PATCH 3/4] Used DQL for non-dynamic query in VisitRepository --- module/Core/src/Repository/VisitRepository.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/module/Core/src/Repository/VisitRepository.php b/module/Core/src/Repository/VisitRepository.php index f67bb726..781df089 100644 --- a/module/Core/src/Repository/VisitRepository.php +++ b/module/Core/src/Repository/VisitRepository.php @@ -12,10 +12,10 @@ class VisitRepository extends EntityRepository implements VisitRepositoryInterfa { public function findUnlocatedVisits(): iterable { - $qb = $this->createQueryBuilder('v'); - $qb->where($qb->expr()->isNull('v.visitLocation')); + $dql = 'SELECT v FROM Shlinkio\Shlink\Core\Entity\Visit AS v WHERE v.visitLocation IS NULL'; + $query = $this->getEntityManager()->createQuery($dql); - return $qb->getQuery()->iterate(); + return $query->iterate(); } /** From d1312e0934493f503362326f5e060dd53b0657bf Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Wed, 19 Dec 2018 14:37:47 +0100 Subject: [PATCH 4/4] Added unreleased changes to changelog --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2918aade..e16b4456 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,29 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org). +## [Unreleased] + +#### Added + +* *Nothing* + +#### Changed + +* [#320](https://github.com/shlinkio/shlink/issues/320) Replaced query builder by plain DQL for all queries which do not need to be dynamically generated. + +#### Deprecated + +* *Nothing* + +#### Removed + +* *Nothing* + +#### Fixed + +* *Nothing* + + ## 1.15.1 - 2018-12-16 #### Added