Skip to content

Commit 81f2057

Browse files
committed
Temp keyword index
1 parent 32ac948 commit 81f2057

6 files changed

Lines changed: 159 additions & 20 deletions

File tree

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace DoctrineMigrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
final class Version20260323085127 extends AbstractMigration
11+
{
12+
public function getDescription(): string
13+
{
14+
return 'Add index to version keyword association';
15+
}
16+
17+
public function up(Schema $schema): void
18+
{
19+
$this->addSql(<<<'SQL'
20+
ALTER TABLE version_keyword ADD id INT GENERATED BY DEFAULT AS IDENTITY
21+
SQL);
22+
$this->addSql(<<<'SQL'
23+
ALTER TABLE version_keyword ADD index INT DEFAULT NULL
24+
SQL);
25+
$this->addSql(<<<'SQL'
26+
UPDATE version_keyword vk
27+
SET "index" = sub.row_num - 1
28+
FROM (
29+
SELECT version_id, keyword_id, ROW_NUMBER() OVER (PARTITION BY version_id ORDER BY keyword_id) AS row_num
30+
FROM version_keyword
31+
) sub
32+
WHERE vk.version_id = sub.version_id AND vk.keyword_id = sub.keyword_id
33+
SQL);
34+
$this->addSql(<<<'SQL'
35+
ALTER TABLE version_keyword ALTER COLUMN index SET NOT NULL
36+
SQL);
37+
$this->addSql(<<<'SQL'
38+
ALTER TABLE version_keyword DROP CONSTRAINT version_keyword_pkey
39+
SQL);
40+
$this->addSql(<<<'SQL'
41+
ALTER TABLE version_keyword ADD PRIMARY KEY (id)
42+
SQL);
43+
}
44+
45+
public function down(Schema $schema): void
46+
{
47+
$this->addSql(<<<'SQL'
48+
ALTER TABLE version_keyword DROP CONSTRAINT version_keyword_pkey
49+
SQL);
50+
$this->addSql(<<<'SQL'
51+
ALTER TABLE version_keyword DROP id
52+
SQL);
53+
$this->addSql(<<<'SQL'
54+
ALTER TABLE version_keyword DROP index
55+
SQL);
56+
$this->addSql(<<<'SQL'
57+
ALTER TABLE version_keyword ADD PRIMARY KEY (version_id, keyword_id)
58+
SQL);
59+
}
60+
}

src/Doctrine/Entity/Keyword.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ class Keyword
1818
#[ORM\Column(length: 191)]
1919
private string $name;
2020

21-
#[ORM\ManyToMany(targetEntity: Version::class, mappedBy: 'keywords')]
22-
protected Collection $versions;
21+
#[ORM\OneToMany(mappedBy: 'keyword', targetEntity: VersionKeyword::class)]
22+
protected Collection $versionKeywords;
2323

2424
public function __construct(string $name)
2525
{
2626
$this->name = $name;
27-
$this->versions = new ArrayCollection();
27+
$this->versionKeywords = new ArrayCollection();
2828
}
2929

3030
public function getId(): ?int

src/Doctrine/Entity/Version.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ class Version extends TrackedEntity implements \Stringable
7979
#[ORM\OrderBy(['index' => 'ASC'])]
8080
private Collection $suggest;
8181

82-
#[ORM\ManyToMany(targetEntity: Keyword::class, inversedBy: 'versions', cascade: ['persist', 'detach', 'remove'])]
82+
#[ORM\OneToMany(mappedBy: 'version', targetEntity: VersionKeyword::class, cascade: ['persist', 'detach', 'remove'])]
83+
#[ORM\OrderBy(['index' => 'ASC'])]
8384
private Collection $keywords;
8485

8586
#[ORM\Column]
@@ -354,16 +355,16 @@ public function addSuggestLink(VersionSuggestLink $suggest): void
354355
}
355356

356357
/**
357-
* @return Collection<int, Keyword>
358+
* @return Collection<int, VersionKeyword>
358359
*/
359360
public function getKeywords(): Collection
360361
{
361362
return $this->keywords;
362363
}
363364

364-
public function addKeyword(Keyword $keyword): void
365+
public function addKeyword(VersionKeyword $versionKeyword): void
365366
{
366-
$this->keywords[] = $keyword;
367+
$this->keywords[] = $versionKeyword;
367368
}
368369

369370
public function getAutoload(): array
@@ -642,8 +643,8 @@ public function getBrowsableRepositoryUrl(): ?string
642643
public function toComposerArray(): array
643644
{
644645
$keywords = [];
645-
foreach ($this->getKeywords() as $keyword) {
646-
$keywords[] = $keyword->getName();
646+
foreach ($this->getKeywords() as $versionKeyword) {
647+
$keywords[] = $versionKeyword->getKeyword()->getName();
647648
}
648649

649650
$authors = $this->getAuthors();
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
<?php
2+
3+
namespace CodedMonkey\Dirigent\Doctrine\Entity;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
#[ORM\Entity]
8+
class VersionKeyword
9+
{
10+
#[ORM\Id]
11+
#[ORM\Column]
12+
#[ORM\GeneratedValue]
13+
private ?int $id = null;
14+
15+
#[ORM\ManyToOne(targetEntity: Version::class, inversedBy: 'keywords')]
16+
#[ORM\JoinColumn(nullable: false)]
17+
private Version $version;
18+
19+
#[ORM\ManyToOne(targetEntity: Keyword::class, inversedBy: 'versionKeywords')]
20+
#[ORM\JoinColumn(nullable: false)]
21+
private Keyword $keyword;
22+
23+
#[ORM\Column]
24+
private int $index;
25+
26+
public function getId(): ?int
27+
{
28+
return $this->id;
29+
}
30+
31+
public function getVersion(): Version
32+
{
33+
return $this->version;
34+
}
35+
36+
public function setVersion(Version $version): void
37+
{
38+
$this->version = $version;
39+
}
40+
41+
public function getKeyword(): Keyword
42+
{
43+
return $this->keyword;
44+
}
45+
46+
public function setKeyword(Keyword $keyword): void
47+
{
48+
$this->keyword = $keyword;
49+
}
50+
51+
public function getIndex(): int
52+
{
53+
return $this->index;
54+
}
55+
56+
public function setIndex(int $index): void
57+
{
58+
$this->index = $index;
59+
}
60+
}

src/Package/PackageMetadataResolver.php

Lines changed: 27 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
use CodedMonkey\Dirigent\Doctrine\Entity\VersionProvideLink;
1616
use CodedMonkey\Dirigent\Doctrine\Entity\VersionReplaceLink;
1717
use CodedMonkey\Dirigent\Doctrine\Entity\VersionRequireLink;
18+
use CodedMonkey\Dirigent\Doctrine\Entity\VersionKeyword;
1819
use CodedMonkey\Dirigent\Doctrine\Entity\VersionSuggestLink;
1920
use CodedMonkey\Dirigent\Doctrine\Repository\KeywordRepository;
2021
use CodedMonkey\Dirigent\Doctrine\Repository\RegistryRepository;
@@ -406,25 +407,42 @@ private function updateVersion(Package $package, Version $version, CompletePacka
406407

407408
// Handle keywords
408409
if ($keywordsData = $data->getKeywords()) {
409-
foreach ($version->getKeywords() as $keyword) {
410-
$keywordName = $keyword->getName();
410+
$keywords = [];
411+
$keywordIndex = 0;
412+
foreach ($keywordsData as $keywordName) {
413+
$keywords[$keywordName] = $keywordIndex++;
414+
}
415+
416+
foreach ($version->getKeywords() as $versionKeyword) {
417+
$keywordName = $versionKeyword->getKeyword()->getName();
411418
// Clear keywords that have disappeared (for updates)
412-
if (!in_array($keywordName, $keywordsData, true)) {
413-
$version->getKeywords()->removeElement($keyword);
414-
$em->remove($keyword);
419+
if (!isset($keywords[$keywordName])) {
420+
$version->getKeywords()->removeElement($versionKeyword);
421+
$em->remove($versionKeyword);
415422
} else {
423+
// Update index if it changed
424+
if ($versionKeyword->getIndex() !== $keywords[$keywordName]) {
425+
$versionKeyword->setIndex($keywords[$keywordName]);
426+
}
416427
// Clear those that are already set
417-
$index = array_search($keywordName, $keywordsData, true);
418-
unset($keywordsData[$index]);
428+
unset($keywords[$keywordName]);
419429
}
420430
}
421431

422-
foreach ($keywordsData as $keywordName) {
432+
foreach ($keywords as $keywordName => $keywordIndex) {
423433
$keyword = $this->keywordRepository->getByName($keywordName);
424-
$version->addKeyword($keyword);
434+
$versionKeyword = new VersionKeyword();
435+
$versionKeyword->setKeyword($keyword);
436+
$versionKeyword->setIndex($keywordIndex);
437+
$version->addKeyword($versionKeyword);
438+
$versionKeyword->setVersion($version);
439+
$em->persist($versionKeyword);
425440
}
426441
} elseif (count($version->getKeywords())) {
427442
// Clear existing keywords if present
443+
foreach ($version->getKeywords() as $versionKeyword) {
444+
$em->remove($versionKeyword);
445+
}
428446
$version->getKeywords()->clear();
429447
}
430448

templates/dashboard/packages/package_info.html.twig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
<span class="fa-solid fa-tags fa-fw me-1" title="{{ 'Keywords'|trans }}" aria-hidden="true"></span>
3333

3434
<div class="d-flex flex-wrap gap-2" aria-label="{{ 'Keywords'|trans }}">
35-
{% for keyword in version.keywords %}
36-
<span>{{ keyword.name }}</span>
35+
{% for versionKeyword in version.keywords %}
36+
<span>{{ versionKeyword.keyword.name }}</span>
3737
{% endfor %}
3838
</div>
3939
</div>

0 commit comments

Comments
 (0)