chore(migration): ajouter scripts et migrations de donnees
This commit is contained in:
139
scripts/validate-migration.php
Normal file
139
scripts/validate-migration.php
Normal file
@@ -0,0 +1,139 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
function parseDatabaseUrl(string $url): array
|
||||
{
|
||||
$parts = parse_url($url);
|
||||
if ($parts === false) {
|
||||
throw new RuntimeException('Invalid database URL.');
|
||||
}
|
||||
|
||||
$host = $parts['host'] ?? 'localhost';
|
||||
$port = isset($parts['port']) ? (int) $parts['port'] : 5432;
|
||||
$user = $parts['user'] ?? '';
|
||||
$pass = $parts['pass'] ?? '';
|
||||
$db = ltrim($parts['path'] ?? '', '/');
|
||||
|
||||
return [
|
||||
'dsn' => sprintf('pgsql:host=%s;port=%d;dbname=%s', $host, $port, $db),
|
||||
'user' => $user,
|
||||
'pass' => $pass,
|
||||
];
|
||||
}
|
||||
|
||||
function connect(string $url): PDO
|
||||
{
|
||||
$config = parseDatabaseUrl($url);
|
||||
$pdo = new PDO($config['dsn'], $config['user'], $config['pass'], [
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
|
||||
]);
|
||||
|
||||
return $pdo;
|
||||
}
|
||||
|
||||
$sourceUrl = getenv('SOURCE_DATABASE_URL') ?: '';
|
||||
$targetUrl = getenv('TARGET_DATABASE_URL') ?: '';
|
||||
|
||||
if ($sourceUrl === '' || $targetUrl === '') {
|
||||
fwrite(STDERR, "Usage: SOURCE_DATABASE_URL=... TARGET_DATABASE_URL=... php scripts/validate-migration.php\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$tables = [
|
||||
'sites',
|
||||
'type_machines',
|
||||
'machines',
|
||||
'model_types',
|
||||
'composants',
|
||||
'pieces',
|
||||
'products',
|
||||
'constructeurs',
|
||||
'documents',
|
||||
'custom_fields',
|
||||
'custom_field_values',
|
||||
'machine_component_links',
|
||||
'machine_piece_links',
|
||||
'machine_product_links',
|
||||
'type_machine_component_requirements',
|
||||
'type_machine_piece_requirements',
|
||||
'type_machine_product_requirements',
|
||||
'_machineconstructeurs',
|
||||
'_composantconstructeurs',
|
||||
'_piececonstructeurs',
|
||||
'_productconstructeurs',
|
||||
'profiles',
|
||||
];
|
||||
|
||||
$skipTables = array_filter(array_map('trim', explode(',', getenv('SKIP_TABLES') ?: 'profiles')));
|
||||
|
||||
$sourceTableMap = [
|
||||
'model_types' => ['ModelType', 'model_types'],
|
||||
'_machineconstructeurs' => ['_MachineConstructeurs', '_machineconstructeurs'],
|
||||
'_composantconstructeurs' => ['_ComposantConstructeurs', '_composantconstructeurs'],
|
||||
'_piececonstructeurs' => ['_PieceConstructeurs', '_piececonstructeurs'],
|
||||
'_productconstructeurs' => ['_ProductConstructeurs', '_productconstructeurs'],
|
||||
];
|
||||
|
||||
function resolveTable(PDO $db, array $candidates): ?string
|
||||
{
|
||||
foreach ($candidates as $candidate) {
|
||||
$exists = (bool) $db
|
||||
->query(sprintf("SELECT to_regclass('public.%s')", $candidate))
|
||||
->fetchColumn();
|
||||
if ($exists) {
|
||||
return $candidate;
|
||||
}
|
||||
|
||||
$quoted = (bool) $db
|
||||
->query(sprintf("SELECT to_regclass('public.\"%s\"')", $candidate))
|
||||
->fetchColumn();
|
||||
if ($quoted) {
|
||||
return sprintf('"%s"', $candidate);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
$source = connect($sourceUrl);
|
||||
$target = connect($targetUrl);
|
||||
|
||||
$hasDifferences = false;
|
||||
|
||||
foreach ($tables as $table) {
|
||||
if (in_array($table, $skipTables, true)) {
|
||||
continue;
|
||||
}
|
||||
$sourceCandidates = $sourceTableMap[$table] ?? [$table];
|
||||
$sourceTable = resolveTable($source, $sourceCandidates);
|
||||
$sourceExists = $sourceTable !== null;
|
||||
$targetExists = (bool) $target
|
||||
->query(sprintf("SELECT to_regclass('public.%s')", $table))
|
||||
->fetchColumn();
|
||||
|
||||
if (!$sourceExists || !$targetExists) {
|
||||
$hasDifferences = true;
|
||||
printf(
|
||||
"%s: source=%s target=%s\n",
|
||||
$table,
|
||||
$sourceExists ? 'exists' : 'missing',
|
||||
$targetExists ? 'exists' : 'missing'
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
||||
$sourceCount = (int) $source->query(sprintf('SELECT COUNT(*) FROM public.%s', $sourceTable))->fetchColumn();
|
||||
$targetCount = (int) $target->query(sprintf('SELECT COUNT(*) FROM public.%s', $table))->fetchColumn();
|
||||
|
||||
if ($sourceCount !== $targetCount) {
|
||||
$hasDifferences = true;
|
||||
printf("%s: source=%d target=%d\n", $table, $sourceCount, $targetCount);
|
||||
}
|
||||
}
|
||||
|
||||
if ($hasDifferences) {
|
||||
exit(2);
|
||||
}
|
||||
|
||||
echo "Counts match for all tables.\n";
|
||||
Reference in New Issue
Block a user