Skip to content

Commit 8b3b1aa

Browse files
committed
Migrate array columns to json types
To do the migration for local dev envs, run: bin/console packagist:migrate-db bin/console doctrine:schema:upd --force --complete
1 parent 5099cb5 commit 8b3b1aa

File tree

5 files changed

+133
-15
lines changed

5 files changed

+133
-15
lines changed

composer.lock

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php declare(strict_types=1);
2+
3+
/*
4+
* This file is part of Packagist.
5+
*
6+
* (c) Jordi Boggiano <j.boggiano@seld.be>
7+
* Nils Adermann <naderman@naderman.de>
8+
*
9+
* For the full copyright and license information, please view the LICENSE
10+
* file that was distributed with this source code.
11+
*/
12+
13+
namespace App\Command;
14+
15+
use App\Entity\Dist;
16+
use App\Entity\DistType;
17+
use App\Entity\Version;
18+
use App\Service\FallbackGitHubAuthProvider;
19+
use Composer\Util\HttpDownloader;
20+
use Doctrine\DBAL\ArrayParameterType;
21+
use Doctrine\Persistence\ManagerRegistry;
22+
use App\Entity\Package;
23+
use App\Package\V2Dumper;
24+
use App\Service\Locker;
25+
use Psr\Log\LoggerInterface;
26+
use Seld\Signal\SignalHandler;
27+
use Symfony\Component\Console\Command\Command;
28+
use Symfony\Component\Console\Input\InputInterface;
29+
use Symfony\Component\Console\Input\InputOption;
30+
use Symfony\Component\Console\Output\OutputInterface;
31+
use Symfony\Component\HttpClient\Exception\TimeoutException;
32+
use Symfony\Component\HttpClient\Exception\TransportException;
33+
use Symfony\Component\HttpClient\NoPrivateNetworkHttpClient;
34+
use ZipArchive;
35+
36+
class MigrateDataTypesCommand extends Command
37+
{
38+
use \App\Util\DoctrineTrait;
39+
40+
public function __construct(
41+
private readonly ManagerRegistry $doctrine,
42+
) {
43+
parent::__construct();
44+
}
45+
46+
protected function configure(): void
47+
{
48+
$this
49+
->setName('packagist:migrate-db')
50+
->setDescription('Migrate DB data types from array to json type, run this command once to migrate old data')
51+
->setDefinition([
52+
])
53+
;
54+
}
55+
56+
protected function execute(InputInterface $input, OutputInterface $output): int
57+
{
58+
do {
59+
$em = $this->getEM();
60+
$versions = $em->getConnection()->fetchAllAssociative('SELECT id, extra FROM package_version WHERE extra LIKE "a%" LIMIT 5000');
61+
62+
$output->writeln(count($versions).' versions to update');
63+
$em->getConnection()->beginTransaction();
64+
foreach ($versions as $version) {
65+
$extra = unserialize($version['extra']);
66+
if ($extra === false) {
67+
throw new \UnexpectedValueException('Could not parse '.$version['extra']);
68+
}
69+
$extra = json_encode($extra);
70+
if ($extra === false) {
71+
throw new \UnexpectedValueException('Failed json-encoding '.$version['extra']);
72+
}
73+
$em->getConnection()->update('package_version', ['extra' => $extra], ['id' => $version['id']]);
74+
}
75+
$em->getConnection()->commit();
76+
} while (count($versions) > 0);
77+
78+
do {
79+
$emptyRefs = $em->getConnection()->fetchAllAssociative('SELECT package_id, emptyReferences FROM empty_references WHERE emptyReferences LIKE "a%" LIMIT 1000');
80+
81+
$output->writeln(count($emptyRefs).' empty refs to update');
82+
$em->getConnection()->beginTransaction();
83+
foreach ($emptyRefs as $emptyRef) {
84+
$emptyReferences = unserialize($emptyRef['emptyReferences']);
85+
if ($emptyReferences === false) {
86+
throw new \UnexpectedValueException('Could not parse '.$emptyRef['emptyReferences']);
87+
}
88+
$emptyReferences = json_encode($emptyReferences);
89+
if ($emptyReferences === false) {
90+
throw new \UnexpectedValueException('Failed json-encoding '.$emptyRef['emptyReferences']);
91+
}
92+
$em->getConnection()->update('empty_references', ['emptyReferences' => $emptyReferences], ['package_id' => $emptyRef['package_id']]);
93+
}
94+
$em->getConnection()->commit();
95+
} while (count($emptyRefs) > 0);
96+
97+
do {
98+
$users = $em->getConnection()->fetchAllAssociative('SELECT id, roles FROM fos_user WHERE roles LIKE "a%" LIMIT 1000');
99+
100+
$output->writeln(count($users).' users to update');
101+
$em->getConnection()->beginTransaction();
102+
foreach ($users as $user) {
103+
$roles = unserialize($user['roles']);
104+
if ($roles === false) {
105+
throw new \UnexpectedValueException('Could not parse '.$user['roles']);
106+
}
107+
$roles = json_encode($roles);
108+
if ($roles === false) {
109+
throw new \UnexpectedValueException('Failed json-encoding '.$user['roles']);
110+
}
111+
$em->getConnection()->update('fos_user', ['roles' => $roles], ['id' => $user['id']]);
112+
}
113+
$em->getConnection()->commit();
114+
} while (count($users) > 0);
115+
116+
return 0;
117+
}
118+
}

src/Entity/EmptyReferenceCache.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ class EmptyReferenceCache
2828
/**
2929
* @var list<string>
3030
*/
31-
#[ORM\Column(type: 'array')]
31+
#[ORM\Column(type: 'json')]
3232
private array $emptyReferences = [];
3333

3434
public function __construct(Package $package)

src/Entity/User.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class User implements UserInterface, TwoFactorInterface, BackupCodeInterface, Eq
6565
/**
6666
* @var list<string>
6767
*/
68-
#[ORM\Column(type: 'array')]
68+
#[ORM\Column(type: 'json')]
6969
private array $roles = [];
7070

7171
/**

src/Entity/Version.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ class Version
8282
/**
8383
* @var array<mixed>
8484
*/
85-
#[ORM\Column(type: 'array')]
85+
#[ORM\Column(type: 'json')]
8686
private array $extra = [];
8787

8888
/**

0 commit comments

Comments
 (0)