Skip to content

Commit 3a82df1

Browse files
committed
Create generalized package link entities
1 parent e764646 commit 3a82df1

File tree

9 files changed

+309
-47
lines changed

9 files changed

+309
-47
lines changed
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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 Version20250319194658 extends AbstractMigration
11+
{
12+
public function getDescription(): string
13+
{
14+
return 'Add generalized package link tables';
15+
}
16+
17+
public function up(Schema $schema): void
18+
{
19+
$this->addSql('CREATE TABLE dependent (dependent_package_name VARCHAR(191) NOT NULL, dev_dependency BOOLEAN NOT NULL, package_id INT NOT NULL, PRIMARY KEY(package_id, dependent_package_name, dev_dependency))');
20+
$this->addSql('CREATE INDEX IDX_BB9077A4F44CABFF ON dependent (package_id)');
21+
$this->addSql('CREATE TABLE provider (provided_package_name VARCHAR(191) NOT NULL, package_id INT NOT NULL, PRIMARY KEY(package_id, provided_package_name))');
22+
$this->addSql('CREATE INDEX IDX_92C4739CF44CABFF ON provider (package_id)');
23+
$this->addSql('CREATE TABLE suggester (suggested_package_name VARCHAR(191) NOT NULL, package_id INT NOT NULL, PRIMARY KEY(package_id, suggested_package_name))');
24+
$this->addSql('CREATE INDEX IDX_4D5681F2F44CABFF ON suggester (package_id)');
25+
$this->addSql('ALTER TABLE dependent ADD CONSTRAINT FK_BB9077A4F44CABFF FOREIGN KEY (package_id) REFERENCES package (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
26+
$this->addSql('ALTER TABLE provider ADD CONSTRAINT FK_92C4739CF44CABFF FOREIGN KEY (package_id) REFERENCES package (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
27+
$this->addSql('ALTER TABLE suggester ADD CONSTRAINT FK_4D5681F2F44CABFF FOREIGN KEY (package_id) REFERENCES package (id) NOT DEFERRABLE INITIALLY IMMEDIATE');
28+
$this->addSql('ALTER TABLE conflict_link RENAME COLUMN package_name TO linked_package_name');
29+
$this->addSql('ALTER TABLE conflict_link RENAME COLUMN package_version TO linked_version_constraint');
30+
$this->addSql('ALTER TABLE dev_require_link RENAME COLUMN package_name TO linked_package_name');
31+
$this->addSql('ALTER TABLE dev_require_link RENAME COLUMN package_version TO linked_version_constraint');
32+
$this->addSql('ALTER TABLE provide_link RENAME COLUMN package_name TO linked_package_name');
33+
$this->addSql('ALTER TABLE provide_link RENAME COLUMN package_version TO linked_version_constraint');
34+
$this->addSql('ALTER TABLE replace_link RENAME COLUMN package_name TO linked_package_name');
35+
$this->addSql('ALTER TABLE replace_link RENAME COLUMN package_version TO linked_version_constraint');
36+
$this->addSql('ALTER TABLE require_link RENAME COLUMN package_name TO linked_package_name');
37+
$this->addSql('ALTER TABLE require_link RENAME COLUMN package_version TO linked_version_constraint');
38+
$this->addSql('ALTER TABLE suggest_link RENAME COLUMN package_name TO linked_package_name');
39+
$this->addSql('ALTER TABLE suggest_link RENAME COLUMN package_version TO linked_version_constraint');
40+
}
41+
42+
public function down(Schema $schema): void
43+
{
44+
$this->addSql('ALTER TABLE dependent DROP CONSTRAINT FK_BB9077A4F44CABFF');
45+
$this->addSql('ALTER TABLE provider DROP CONSTRAINT FK_92C4739CF44CABFF');
46+
$this->addSql('ALTER TABLE suggester DROP CONSTRAINT FK_4D5681F2F44CABFF');
47+
$this->addSql('DROP TABLE dependent');
48+
$this->addSql('DROP TABLE provider');
49+
$this->addSql('DROP TABLE suggester');
50+
$this->addSql('ALTER TABLE suggest_link RENAME COLUMN linked_package_name TO package_name');
51+
$this->addSql('ALTER TABLE suggest_link RENAME COLUMN linked_version_constraint TO package_version');
52+
$this->addSql('ALTER TABLE provide_link RENAME COLUMN linked_package_name TO package_name');
53+
$this->addSql('ALTER TABLE provide_link RENAME COLUMN linked_version_constraint TO package_version');
54+
$this->addSql('ALTER TABLE dev_require_link RENAME COLUMN linked_package_name TO package_name');
55+
$this->addSql('ALTER TABLE dev_require_link RENAME COLUMN linked_version_constraint TO package_version');
56+
$this->addSql('ALTER TABLE conflict_link RENAME COLUMN linked_package_name TO package_name');
57+
$this->addSql('ALTER TABLE conflict_link RENAME COLUMN linked_version_constraint TO package_version');
58+
$this->addSql('ALTER TABLE replace_link RENAME COLUMN linked_package_name TO package_name');
59+
$this->addSql('ALTER TABLE replace_link RENAME COLUMN linked_version_constraint TO package_version');
60+
$this->addSql('ALTER TABLE require_link RENAME COLUMN linked_package_name TO package_name');
61+
$this->addSql('ALTER TABLE require_link RENAME COLUMN linked_version_constraint TO package_version');
62+
}
63+
}

phpstan.dist.neon

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,14 @@ parameters:
99
excludePaths:
1010
- tests/bootstrap.php
1111
ignoreErrors:
12-
- '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition::children\(\).#'
13-
- '#Property CodedMonkey\\Dirigent\\Doctrine\\Entity\\[a-zA-Z]+::\$id \(int\|null\) is never assigned int so it can be removed from the property type.#'
12+
- '#^Property CodedMonkey\\Dirigent\\Doctrine\\Entity\\[a-zA-Z]+\:\:\$id \(int\|null\) is never assigned int so it can be removed from the property type\.$#'
13+
-
14+
message: '#^Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition\:\:children\(\)\.$#'
15+
identifier: method.notFound
16+
count: 1
17+
path: src/DependencyInjection/DirigentConfiguration.php
18+
-
19+
message: '#^PHPDoc tag @var with type CodedMonkey\\Dirigent\\Doctrine\\Entity\\PackageLink is not subtype of native type#'
20+
identifier: varTag.nativeType
21+
count: 1
22+
path: src/Package/PackageMetadataResolver.php

src/Doctrine/Entity/Dependent.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
namespace CodedMonkey\Dirigent\Doctrine\Entity;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
#[ORM\Entity]
8+
class Dependent
9+
{
10+
#[ORM\Id, ORM\ManyToOne(targetEntity: Package::class), ORM\JoinColumn(nullable: false)]
11+
private ?Package $package = null;
12+
13+
#[ORM\Id, ORM\Column(length: 191)]
14+
private string $dependentPackageName;
15+
16+
#[ORM\Id, ORM\Column]
17+
private bool $devDependency;
18+
19+
public function getPackage(): ?Package
20+
{
21+
return $this->package;
22+
}
23+
24+
public function setPackage(Package $package): static
25+
{
26+
$this->package = $package;
27+
28+
return $this;
29+
}
30+
31+
public function getDependentPackageName(): string
32+
{
33+
return $this->dependentPackageName;
34+
}
35+
36+
public function setDependentPackageName(string $packageName): static
37+
{
38+
$this->dependentPackageName = $packageName;
39+
40+
return $this;
41+
}
42+
43+
public function isDevDependency(): bool
44+
{
45+
return $this->devDependency;
46+
}
47+
48+
public function setDevDependency(bool $devDependency): static
49+
{
50+
$this->devDependency = $devDependency;
51+
52+
return $this;
53+
}
54+
}

src/Doctrine/Entity/PackageLink.php

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,58 +13,46 @@ abstract class PackageLink
1313
#[ORM\GeneratedValue]
1414
private ?int $id = null;
1515

16+
protected Version $version;
17+
1618
#[ORM\Column(length: 191)]
17-
private string $packageName;
19+
private string $linkedPackageName;
1820

1921
#[ORM\Column(type: Types::TEXT)]
20-
private string $packageVersion;
21-
22-
/**
23-
* Base property holding the version - this must remain protected since it
24-
* is redefined with an attribute in the child class.
25-
*/
26-
protected Version $version;
22+
private string $linkedVersionConstraint;
2723

2824
public function getId(): ?int
2925
{
3026
return $this->id;
3127
}
3228

33-
public function getPackageName(): string
34-
{
35-
return $this->packageName;
36-
}
37-
38-
public function setPackageName(string $packageName): void
29+
public function getVersion(): Version
3930
{
40-
$this->packageName = $packageName;
31+
return $this->version;
4132
}
4233

43-
public function getPackageVersion(): string
34+
public function setVersion(Version $version): void
4435
{
45-
return $this->packageVersion;
36+
$this->version = $version;
4637
}
4738

48-
public function setPackageVersion(string $packageVersion): void
39+
public function getLinkedPackageName(): string
4940
{
50-
$this->packageVersion = $packageVersion;
41+
return $this->linkedPackageName;
5142
}
5243

53-
public function getVersion(): ?Version
44+
public function setLinkedPackageName(string $packageName): void
5445
{
55-
return $this->version;
46+
$this->linkedPackageName = $packageName;
5647
}
5748

58-
public function setVersion(Version $version): void
49+
public function getLinkedVersionConstraint(): string
5950
{
60-
$this->version = $version;
51+
return $this->linkedVersionConstraint;
6152
}
6253

63-
/**
64-
* @return non-empty-array<string, string>
65-
*/
66-
public function toArray(): array
54+
public function setLinkedVersionConstraint(string $packageVersion): void
6755
{
68-
return [$this->getPackageName() => $this->getPackageVersion()];
56+
$this->linkedVersionConstraint = $packageVersion;
6957
}
7058
}

src/Doctrine/Entity/Provider.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace CodedMonkey\Dirigent\Doctrine\Entity;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
#[ORM\Entity]
8+
class Provider
9+
{
10+
#[ORM\Id, ORM\ManyToOne(targetEntity: Package::class), ORM\JoinColumn(nullable: false)]
11+
private ?Package $package = null;
12+
13+
#[ORM\Id, ORM\Column(length: 191)]
14+
private string $providedPackageName;
15+
16+
public function getPackage(): ?Package
17+
{
18+
return $this->package;
19+
}
20+
21+
public function setPackage(Package $package): static
22+
{
23+
$this->package = $package;
24+
25+
return $this;
26+
}
27+
28+
public function getProvidedPackageName(): string
29+
{
30+
return $this->providedPackageName;
31+
}
32+
33+
public function setProvidedPackageName(string $packageName): static
34+
{
35+
$this->providedPackageName = $packageName;
36+
37+
return $this;
38+
}
39+
}

src/Doctrine/Entity/Suggester.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
namespace CodedMonkey\Dirigent\Doctrine\Entity;
4+
5+
use Doctrine\ORM\Mapping as ORM;
6+
7+
#[ORM\Entity]
8+
class Suggester
9+
{
10+
#[ORM\Id, ORM\ManyToOne(targetEntity: Package::class), ORM\JoinColumn(nullable: false)]
11+
private ?Package $package = null;
12+
13+
#[ORM\Id, ORM\Column(length: 191)]
14+
private string $suggestedPackageName;
15+
16+
public function getPackage(): ?Package
17+
{
18+
return $this->package;
19+
}
20+
21+
public function setPackage(Package $package): static
22+
{
23+
$this->package = $package;
24+
25+
return $this;
26+
}
27+
28+
public function getSuggestedPackageName(): string
29+
{
30+
return $this->suggestedPackageName;
31+
}
32+
33+
public function setSuggestedPackageName(string $packageName): static
34+
{
35+
$this->suggestedPackageName = $packageName;
36+
37+
return $this;
38+
}
39+
}

src/Doctrine/Entity/Version.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -683,8 +683,7 @@ public function toComposerArray(): array
683683
foreach ($supportedLinkTypes as $method => $linkType) {
684684
/** @var PackageLink $link */
685685
foreach ($this->{'get' . $method}() as $link) {
686-
$link = $link->toArray();
687-
$data[$linkType][key($link)] = current($link);
686+
$data[$linkType][$link->getLinkedPackageName()] = $link->getLinkedVersionConstraint();
688687
}
689688
}
690689

src/Doctrine/Repository/PackageRepository.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ public function save(Package $entity, bool $flush = false): void
4040

4141
public function remove(Package $entity, bool $flush = false): void
4242
{
43+
$this->deletePackageLinks($entity->getId());
44+
4345
$this->getEntityManager()->remove($entity);
4446

4547
if ($flush) {
@@ -82,4 +84,44 @@ public function getAllPackageIds(): array
8284

8385
return $connection->fetchAllAssociative('SELECT id FROM package ORDER BY id');
8486
}
87+
88+
public function updatePackageLinks(int $packageId, int $versionId): void
89+
{
90+
$connection = $this->getEntityManager()->getConnection();
91+
$connection->beginTransaction();
92+
93+
try {
94+
$this->deletePackageLinks($packageId);
95+
96+
$connection->executeStatement(
97+
'INSERT INTO dependent (package_id, dependent_package_name, dev_dependency) SELECT :id, linked_package_name, :dev FROM require_link WHERE version_id = :version',
98+
['id' => $packageId, 'version' => $versionId, 'dev' => 0],
99+
);
100+
$connection->executeStatement(
101+
'INSERT INTO dependent (package_id, dependent_package_name, dev_dependency) SELECT :id, linked_package_name, :dev FROM dev_require_link WHERE version_id = :version',
102+
['id' => $packageId, 'version' => $versionId, 'dev' => 1],
103+
);
104+
$connection->executeStatement(
105+
'INSERT INTO suggester (package_id, suggested_package_name) SELECT :id, linked_package_name FROM suggest_link WHERE version_id = :version',
106+
['id' => $packageId, 'version' => $versionId],
107+
);
108+
$connection->executeStatement(
109+
'INSERT INTO provider (package_id, provided_package_name) SELECT :id, linked_package_name FROM provide_link WHERE version_id = :version',
110+
['id' => $packageId, 'version' => $versionId],
111+
);
112+
} catch (\Throwable $exception) {
113+
$connection->rollBack();
114+
throw $exception;
115+
}
116+
117+
$connection->commit();
118+
}
119+
120+
public function deletePackageLinks(int $packageId): void
121+
{
122+
$connection = $this->getEntityManager()->getConnection();
123+
$connection->executeStatement('DELETE FROM dependent WHERE package_id = :id', ['id' => $packageId]);
124+
$connection->executeStatement('DELETE FROM provider WHERE package_id = :id', ['id' => $packageId]);
125+
$connection->executeStatement('DELETE FROM suggester WHERE package_id = :id', ['id' => $packageId]);
126+
}
85127
}

0 commit comments

Comments
 (0)