chore(migration): ajouter scripts et migrations de donnees

This commit is contained in:
2026-01-11 17:05:50 +01:00
parent fab1d25871
commit 15e0b23f15
6 changed files with 498 additions and 32 deletions

View File

@@ -0,0 +1,5 @@
INSERT INTO public.profiles (id, firstname, lastname, isactive, createdat, updatedat)
VALUES
('admin-default-profile', 'Admin', 'General', true, '2025-09-23 13:09:47.804', '2025-09-23 13:09:47.804'),
('cmhab2j3x003g47v77xhnm1ff', 'Elodie', 'Souriau', true, '2025-10-28 08:29:25.437', '2025-10-28 08:29:25.437')
ON CONFLICT (id) DO NOTHING;

View File

@@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail
SOURCE_DB="${SOURCE_DB:-inventory_data}"
TARGET_DB="${TARGET_DB:-inventory}"
PGHOST="${PGHOST:-localhost}"
PGPORT="${PGPORT:-5433}"
PGUSER="${PGUSER:-postgres}"
PGPASSWORD="${PGPASSWORD:-postgres}"
DUMP_FILE="${DUMP_FILE:-/tmp/inventory_data_dump.sql}"
export PGPASSWORD
EXCLUDE_TABLES=(
"doctrine_migration_versions"
"migration_versions"
"_prisma_migrations"
"profiles"
)
EXCLUDE_ARGS=()
for table in "${EXCLUDE_TABLES[@]}"; do
EXCLUDE_ARGS+=(--exclude-table-data="$table")
done
echo "Dumping data from ${SOURCE_DB}..."
pg_dump \
--data-only \
--inserts \
--no-owner \
--no-privileges \
"${EXCLUDE_ARGS[@]}" \
-h "${PGHOST}" \
-p "${PGPORT}" \
-U "${PGUSER}" \
"${SOURCE_DB}" > "${DUMP_FILE}"
echo "Restoring data into ${TARGET_DB}..."
psql \
-h "${PGHOST}" \
-p "${PGPORT}" \
-U "${PGUSER}" \
"${TARGET_DB}" < "${DUMP_FILE}"
echo "Done. Data copied from ${SOURCE_DB} to ${TARGET_DB}."

80
scripts/normalize-dump.py Normal file
View File

@@ -0,0 +1,80 @@
#!/usr/bin/env python3
import sys
TABLE_NAME_MAP = {
"ModelType": "model_types",
}
def normalize_identifiers(sql: str) -> str:
out = []
i = 0
in_single = False
length = len(sql)
while i < length:
ch = sql[i]
if in_single:
if ch == "'":
if i + 1 < length and sql[i + 1] == "'":
out.append("''")
i += 2
continue
in_single = False
out.append(ch)
i += 1
continue
if ch == "'":
in_single = True
out.append(ch)
i += 1
continue
if ch == '"':
i += 1
ident = []
while i < length:
if sql[i] == '"':
break
ident.append(sql[i])
i += 1
ident_str = ''.join(ident)
mapped = TABLE_NAME_MAP.get(ident_str)
if mapped is not None:
out.append(mapped)
else:
out.append(ident_str.lower())
if i < length and sql[i] == '"':
i += 1
continue
out.append(ch)
i += 1
return ''.join(out)
def main() -> int:
if len(sys.argv) != 3:
print("Usage: scripts/normalize-dump.py <input.sql> <output.sql>", file=sys.stderr)
return 1
src = sys.argv[1]
dst = sys.argv[2]
with open(src, "r", encoding="utf-8") as f:
data = f.read()
normalized = normalize_identifiers(data)
with open(dst, "w", encoding="utf-8") as f:
f.write(normalized)
return 0
if __name__ == "__main__":
raise SystemExit(main())

View 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";