Skip to content

Commit 9c3d375

Browse files
committed
Optimize fetching of metadata associations
1 parent 6c0a8e3 commit 9c3d375

File tree

3 files changed

+78
-20
lines changed

3 files changed

+78
-20
lines changed

src/Controller/Dashboard/DashboardPackagesInfoController.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44

55
use CodedMonkey\Dirigent\Attribute\IsGrantedAccess;
66
use CodedMonkey\Dirigent\Attribute\MapPackage;
7+
use CodedMonkey\Dirigent\Doctrine\Entity\Metadata;
78
use CodedMonkey\Dirigent\Doctrine\Entity\Package;
89
use CodedMonkey\Dirigent\Doctrine\Entity\PackageProvideLink;
910
use CodedMonkey\Dirigent\Doctrine\Entity\PackageRequireLink;
1011
use CodedMonkey\Dirigent\Doctrine\Entity\PackageSuggestLink;
1112
use CodedMonkey\Dirigent\Doctrine\Entity\Version;
13+
use CodedMonkey\Dirigent\Doctrine\Repository\MetadataRepository;
1214
use CodedMonkey\Dirigent\EasyAdmin\PackagePaginator;
1315
use Doctrine\ORM\EntityManagerInterface;
1416
use Doctrine\ORM\QueryBuilder;
@@ -44,6 +46,10 @@ public function info(#[MapPackage] Package $package): Response
4446
#[IsGrantedAccess]
4547
public function versionInfo(#[MapPackage] Package $package, #[MapPackage] Version $version): Response
4648
{
49+
/** @var MetadataRepository $metadataRepository */
50+
$metadataRepository = $this->entityManager->getRepository(Metadata::class);
51+
$metadataRepository->fetchMetadataCollections($version->getCurrentMetadata());
52+
4753
$dependentCount = $this->entityManager->getRepository(PackageRequireLink::class)->count(['linkedPackageName' => $package->getName()]);
4854
$implementationCount = $this->entityManager->getRepository(PackageProvideLink::class)->count(['linkedPackageName' => $package->getName(), 'implementation' => true]);
4955
$providerCount = $this->entityManager->getRepository(PackageProvideLink::class)->count(['linkedPackageName' => $package->getName(), 'implementation' => false]);

src/Doctrine/Entity/Metadata.php

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
use Composer\Pcre\Preg;
99
use Doctrine\Common\Collections\ArrayCollection;
1010
use Doctrine\Common\Collections\Collection;
11+
use Doctrine\Common\Collections\Criteria;
12+
use Doctrine\Common\Collections\Order;
13+
use Doctrine\Common\Collections\Selectable;
1114
use Doctrine\DBAL\Types\Types;
1215
use Doctrine\ORM\Mapping as ORM;
1316

@@ -98,49 +101,43 @@ class Metadata extends TrackedEntity implements \Stringable
98101
private Package $package;
99102

100103
/**
101-
* @var Collection<int, MetadataRequireLink>
104+
* @var Collection<int, MetadataRequireLink>&Selectable
102105
*/
103106
#[ORM\OneToMany(targetEntity: MetadataRequireLink::class, mappedBy: 'metadata', cascade: ['persist', 'detach'])]
104-
#[ORM\OrderBy(['index' => 'ASC'])]
105107
private Collection $requireLinks;
106108

107109
/**
108-
* @var Collection<int, MetadataDevRequireLink>
110+
* @var Collection<int, MetadataDevRequireLink>&Selectable
109111
*/
110112
#[ORM\OneToMany(targetEntity: MetadataDevRequireLink::class, mappedBy: 'metadata', cascade: ['persist', 'detach'])]
111-
#[ORM\OrderBy(['index' => 'ASC'])]
112113
private Collection $devRequireLinks;
113114

114115
/**
115-
* @var Collection<int, MetadataConflictLink>
116+
* @var Collection<int, MetadataConflictLink>&Selectable
116117
*/
117118
#[ORM\OneToMany(targetEntity: MetadataConflictLink::class, mappedBy: 'metadata', cascade: ['persist', 'detach'])]
118-
#[ORM\OrderBy(['index' => 'ASC'])]
119119
private Collection $conflictLinks;
120120

121121
/**
122-
* @var Collection<int, MetadataProvideLink>
122+
* @var Collection<int, MetadataProvideLink>&Selectable
123123
*/
124124
#[ORM\OneToMany(targetEntity: MetadataProvideLink::class, mappedBy: 'metadata', cascade: ['persist', 'detach'])]
125-
#[ORM\OrderBy(['index' => 'ASC'])]
126125
private Collection $provideLinks;
127126

128127
/**
129-
* @var Collection<int, MetadataReplaceLink>
128+
* @var Collection<int, MetadataReplaceLink>&Selectable
130129
*/
131130
#[ORM\OneToMany(targetEntity: MetadataReplaceLink::class, mappedBy: 'metadata', cascade: ['persist', 'detach'])]
132-
#[ORM\OrderBy(['index' => 'ASC'])]
133131
private Collection $replaceLinks;
134132

135133
/**
136-
* @var Collection<int, MetadataSuggestLink>
134+
* @var Collection<int, MetadataSuggestLink>&Selectable
137135
*/
138136
#[ORM\OneToMany(targetEntity: MetadataSuggestLink::class, mappedBy: 'metadata', cascade: ['persist', 'detach'])]
139-
#[ORM\OrderBy(['index' => 'ASC'])]
140137
private Collection $suggestLinks;
141138

142139
/**
143-
* @var Collection<int, MetadataKeyword>
140+
* @var Collection<int, MetadataKeyword>&Selectable
144141
*/
145142
#[ORM\OneToMany(mappedBy: 'metadata', targetEntity: MetadataKeyword::class, cascade: ['persist', 'detach'])]
146143
private Collection $keywords;
@@ -418,55 +415,55 @@ public function getPackage(): Package
418415
*/
419416
public function getRequireLinks(): Collection
420417
{
421-
return $this->requireLinks;
418+
return self::getOrderedCollection($this->requireLinks);
422419
}
423420

424421
/**
425422
* @return Collection<int, MetadataDevRequireLink>
426423
*/
427424
public function getDevRequireLinks(): Collection
428425
{
429-
return $this->devRequireLinks;
426+
return self::getOrderedCollection($this->devRequireLinks);
430427
}
431428

432429
/**
433430
* @return Collection<int, MetadataConflictLink>
434431
*/
435432
public function getConflictLinks(): Collection
436433
{
437-
return $this->conflictLinks;
434+
return self::getOrderedCollection($this->conflictLinks);
438435
}
439436

440437
/**
441438
* @return Collection<int, MetadataProvideLink>
442439
*/
443440
public function getProvideLinks(): Collection
444441
{
445-
return $this->provideLinks;
442+
return self::getOrderedCollection($this->provideLinks);
446443
}
447444

448445
/**
449446
* @return Collection<int, MetadataReplaceLink>
450447
*/
451448
public function getReplaceLinks(): Collection
452449
{
453-
return $this->replaceLinks;
450+
return self::getOrderedCollection($this->replaceLinks);
454451
}
455452

456453
/**
457454
* @return Collection<int, MetadataSuggestLink>
458455
*/
459456
public function getSuggestLinks(): Collection
460457
{
461-
return $this->suggestLinks;
458+
return self::getOrderedCollection($this->suggestLinks);
462459
}
463460

464461
/**
465462
* @return Collection<int, MetadataKeyword>
466463
*/
467464
public function getKeywords(): Collection
468465
{
469-
return $this->keywords;
466+
return self::getOrderedCollection($this->keywords);
470467
}
471468

472469
public function hasSource(): bool
@@ -675,4 +672,15 @@ public function toComposerArray(): array
675672

676673
return $data;
677674
}
675+
676+
private static function getOrderedCollection(Collection&Selectable $collection): Collection
677+
{
678+
static $criteria = Criteria::create()
679+
->orderBy(['index' => Order::Ascending]);
680+
681+
/** @var Collection $collection */
682+
$collection = $collection->matching($criteria);
683+
684+
return $collection;
685+
}
678686
}

src/Doctrine/Repository/MetadataRepository.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace CodedMonkey\Dirigent\Doctrine\Repository;
44

55
use CodedMonkey\Dirigent\Doctrine\Entity\Metadata;
6+
use CodedMonkey\Dirigent\Entity\MetadataLinkType;
67
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
78
use Doctrine\Persistence\ManagerRegistry;
89

@@ -39,6 +40,49 @@ public function remove(Metadata $entity, bool $flush = false): void
3940
}
4041
}
4142

43+
/**
44+
* Initializes all link and keyword collections for the given metadata.
45+
*/
46+
public function fetchMetadataCollections(Metadata ...$metadata): void
47+
{
48+
if ([] === $metadata) {
49+
return;
50+
}
51+
52+
$metadataCollection = $metadata;
53+
54+
foreach (MetadataLinkType::cases() as $linkType) {
55+
$association = match ($linkType) {
56+
MetadataLinkType::Require => 'requireLinks',
57+
MetadataLinkType::DevRequire => 'devRequireLinks',
58+
MetadataLinkType::Conflict => 'conflictLinks',
59+
MetadataLinkType::Provide => 'provideLinks',
60+
MetadataLinkType::Replace => 'replaceLinks',
61+
MetadataLinkType::Suggest => 'suggestLinks',
62+
};
63+
64+
$this->getEntityManager()->createQueryBuilder()
65+
->select('metadata', $association)
66+
->from(Metadata::class, 'metadata')
67+
->leftJoin("metadata.$association", $association)
68+
->where('metadata IN (:metadata)')
69+
->setParameter('metadata', $metadataCollection)
70+
->getQuery()
71+
->getResult();
72+
}
73+
74+
$this->getEntityManager()->createQueryBuilder()
75+
->select('metadata', 'keywords')
76+
->from(Metadata::class, 'metadata')
77+
->leftJoin('metadata.keywords', 'keywords')
78+
->leftJoin('keywords.keyword', 'keyword')
79+
->addSelect('keyword')
80+
->where('metadata IN (:metadata)')
81+
->setParameter('metadata', $metadataCollection)
82+
->getQuery()
83+
->getResult();
84+
}
85+
4286
public function getNextRevision(Metadata $metadata): int
4387
{
4488
$version = $metadata->getVersion();

0 commit comments

Comments
 (0)