Ajout du dossier api avec la géolocalisation automatique des casernes de pompiers
This commit is contained in:
357
api/scripts/php/migrate.php
Normal file
357
api/scripts/php/migrate.php
Normal file
@@ -0,0 +1,357 @@
|
||||
<?php
|
||||
/**
|
||||
* Script de migration générique pour transférer des données entre les bases geosector et geosector_app
|
||||
*
|
||||
* Usage:
|
||||
* php migrate.php - Exécute toutes les migrations dans l'ordre
|
||||
* php migrate.php <table_name> - Exécute la migration pour une table spécifique
|
||||
*
|
||||
* Options:
|
||||
* --truncate Vide la table cible avant la migration
|
||||
* --create-table Crée la table cible si elle n'existe pas
|
||||
* --help Affiche l'aide
|
||||
*/
|
||||
|
||||
require_once dirname(__DIR__) . '/config.php';
|
||||
|
||||
// Définition des mappages de colonnes pour chaque table
|
||||
$tableMappings = [
|
||||
'x_devises' => [
|
||||
'source_to_target' => [
|
||||
'rowid' => 'id',
|
||||
'active' => 'chk_active'
|
||||
],
|
||||
'primary_key' => 'rowid', // Clé primaire dans la table source
|
||||
'target_primary_key' => 'id' // Clé primaire dans la table cible
|
||||
],
|
||||
'users' => [
|
||||
'source_to_target' => [
|
||||
'id' => 'id',
|
||||
'user_pass_hash' => 'password_hash',
|
||||
'encrypted_user_name' => 'encrypted_last_name',
|
||||
'lang' => 'preferred_language',
|
||||
'chk_active' => 'is_active'
|
||||
],
|
||||
'primary_key' => 'id',
|
||||
'target_primary_key' => 'id',
|
||||
'encrypted_fields' => [
|
||||
'email' => ['field' => 'encrypted_email', 'searchable' => true],
|
||||
'user_name' => ['field' => 'encrypted_last_name', 'searchable' => false],
|
||||
'phone' => ['field' => 'encrypted_phone', 'searchable' => false],
|
||||
'mobile' => ['field' => 'encrypted_mobile', 'searchable' => false]
|
||||
]
|
||||
],
|
||||
// Ajoutez d'autres tables selon les besoins
|
||||
];
|
||||
|
||||
// Fonction pour afficher l'aide
|
||||
function showHelp() {
|
||||
echo "Usage: php migrate.php <table_name> [--truncate] [--create-table]\n";
|
||||
echo "\nOptions disponibles:\n";
|
||||
echo " --truncate Vide la table cible avant la migration\n";
|
||||
echo " --create-table Crée la table cible si elle n'existe pas\n";
|
||||
echo " --help Affiche cette aide\n";
|
||||
echo "\nTables disponibles:\n";
|
||||
|
||||
global $tableMappings;
|
||||
foreach (array_keys($tableMappings) as $table) {
|
||||
echo " - $table\n";
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Définition des scripts de migration disponibles dans l'ordre d'exécution
|
||||
$migrationScripts = [
|
||||
'x_devises' => __DIR__ . '/migrate_x_devises.php',
|
||||
'x_entites_types' => __DIR__ . '/migrate_x_entites_types.php',
|
||||
'x_types_passages' => __DIR__ . '/migrate_x_types_passages.php',
|
||||
'x_types_reglements' => __DIR__ . '/migrate_x_types_reglements.php',
|
||||
'x_users_roles' => __DIR__ . '/migrate_x_users_roles.php',
|
||||
'x_pays' => __DIR__ . '/migrate_x_pays.php',
|
||||
'x_regions' => __DIR__ . '/migrate_x_regions.php',
|
||||
'x_departements' => __DIR__ . '/migrate_x_departements.php',
|
||||
'x_villes' => __DIR__ . '/migrate_x_villes.php',
|
||||
'entites' => __DIR__ . '/migrate_entites.php',
|
||||
'users' => __DIR__ . '/migrate_users.php',
|
||||
'operations' => __DIR__ . '/migrate_operations.php',
|
||||
'ope_sectors' => __DIR__ . '/migrate_ope_sectors.php',
|
||||
'sectors_adresses' => __DIR__ . '/migrate_sectors_adresses.php',
|
||||
'ope_users' => __DIR__ . '/migrate_ope_users.php',
|
||||
'ope_users_sectors' => __DIR__ . '/migrate_ope_users_sectors.php',
|
||||
'ope_pass' => __DIR__ . '/migrate_ope_pass.php',
|
||||
'ope_pass_histo' => __DIR__ . '/migrate_ope_pass_histo.php',
|
||||
'medias' => __DIR__ . '/migrate_medias.php'
|
||||
// Ajoutez d'autres scripts de migration au fur et à mesure
|
||||
];
|
||||
|
||||
// Fonction pour exécuter un script de migration spécifique
|
||||
function executeMigrationScript($scriptPath) {
|
||||
echo "\nExécution du script: " . basename($scriptPath) . "\n";
|
||||
echo "------------------------------------------------\n";
|
||||
|
||||
// Exécuter le script PHP
|
||||
include $scriptPath;
|
||||
|
||||
echo "\n";
|
||||
return true;
|
||||
}
|
||||
|
||||
// Traitement des arguments de ligne de commande
|
||||
$tableName = null;
|
||||
$truncateTable = false;
|
||||
$createTable = false;
|
||||
$runAllScripts = true;
|
||||
|
||||
for ($i = 1; $i < $_SERVER['argc']; $i++) {
|
||||
$arg = $_SERVER['argv'][$i];
|
||||
|
||||
if ($arg === '--help') {
|
||||
showHelp();
|
||||
} elseif ($arg === '--truncate') {
|
||||
$truncateTable = true;
|
||||
} elseif ($arg === '--create-table') {
|
||||
$createTable = true;
|
||||
} elseif (substr($arg, 0, 2) !== '--') {
|
||||
$tableName = $arg;
|
||||
$runAllScripts = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Si aucune table n'est spécifiée, exécuter tous les scripts de migration dans l'ordre
|
||||
if ($runAllScripts) {
|
||||
echo "\nDémarrage de la migration complète de la base de données\n";
|
||||
echo "=======================================================\n";
|
||||
|
||||
$startTime = microtime(true);
|
||||
$successCount = 0;
|
||||
$failCount = 0;
|
||||
|
||||
foreach ($migrationScripts as $table => $scriptPath) {
|
||||
if (file_exists($scriptPath)) {
|
||||
try {
|
||||
executeMigrationScript($scriptPath);
|
||||
$successCount++;
|
||||
} catch (Exception $e) {
|
||||
echo "\nErreur lors de la migration de la table $table: " . $e->getMessage() . "\n";
|
||||
$failCount++;
|
||||
}
|
||||
} else {
|
||||
echo "\nScript de migration introuvable pour la table $table: $scriptPath\n";
|
||||
$failCount++;
|
||||
}
|
||||
}
|
||||
|
||||
$endTime = microtime(true);
|
||||
$executionTime = round($endTime - $startTime, 2);
|
||||
|
||||
echo "\n=======================================================\n";
|
||||
echo "Migration terminée en $executionTime secondes\n";
|
||||
echo "Tables migrées avec succès: $successCount\n";
|
||||
echo "Tables en échec: $failCount\n";
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// Si une table spécifique est demandée, vérifier si un script dédié existe
|
||||
if (isset($migrationScripts[$tableName])) {
|
||||
$scriptPath = $migrationScripts[$tableName];
|
||||
if (file_exists($scriptPath)) {
|
||||
executeMigrationScript($scriptPath);
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Sinon, utiliser la méthode générique de migration (code existant)
|
||||
if (!isset($tableMappings[$tableName])) {
|
||||
echo "Erreur: La table '$tableName' n'est pas configurée pour la migration.\n";
|
||||
echo "Tables disponibles: " . implode(', ', array_keys($tableMappings)) . "\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Création du dossier de logs si nécessaire
|
||||
if (!is_dir(dirname(__DIR__) . '/logs')) {
|
||||
mkdir(dirname(__DIR__) . '/logs', 0755, true);
|
||||
}
|
||||
|
||||
logOperation("Démarrage de la migration de la table $tableName");
|
||||
|
||||
try {
|
||||
// Connexion aux bases de données
|
||||
$sourceDb = getSourceConnection();
|
||||
$targetDb = getTargetConnection();
|
||||
|
||||
// Obtenir le service API pour le chiffrement si nécessaire
|
||||
$apiService = null;
|
||||
if (isset($tableMappings[$tableName]['encrypted_fields'])) {
|
||||
$container = $GLOBALS['container'];
|
||||
$apiService = $container->get('ApiService');
|
||||
}
|
||||
|
||||
// Récupération des données de la source
|
||||
$stmt = $sourceDb->query("SELECT * FROM $tableName");
|
||||
$records = $stmt->fetchAll();
|
||||
|
||||
logOperation("Nombre d'enregistrements à migrer: " . count($records));
|
||||
|
||||
// Vérifier si la table existe dans la cible
|
||||
try {
|
||||
$targetDb->query("SELECT 1 FROM $tableName LIMIT 1");
|
||||
$tableExists = true;
|
||||
} catch (PDOException $e) {
|
||||
$tableExists = false;
|
||||
}
|
||||
|
||||
// Créer la table si elle n'existe pas et si l'option est activée
|
||||
if (!$tableExists && $createTable) {
|
||||
logOperation("La table $tableName n'existe pas dans la base cible. Création de la table...");
|
||||
|
||||
// Récupérer la structure de la table source
|
||||
$stmt = $sourceDb->query("SHOW CREATE TABLE $tableName");
|
||||
$tableStructure = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||
|
||||
if (isset($tableStructure['Create Table'])) {
|
||||
$createTableSql = $tableStructure['Create Table'];
|
||||
|
||||
// Adapter les noms de colonnes selon le mapping
|
||||
$mapping = $tableMappings[$tableName]['source_to_target'];
|
||||
foreach ($mapping as $sourceCol => $targetCol) {
|
||||
$createTableSql = str_replace("`$sourceCol`", "`$targetCol`", $createTableSql);
|
||||
}
|
||||
|
||||
// Remplacer le nom de la clé primaire si nécessaire
|
||||
$sourcePk = $tableMappings[$tableName]['primary_key'];
|
||||
$targetPk = $tableMappings[$tableName]['target_primary_key'];
|
||||
if ($sourcePk !== $targetPk) {
|
||||
$createTableSql = str_replace("PRIMARY KEY (`$sourcePk`)", "PRIMARY KEY (`$targetPk`)", $createTableSql);
|
||||
}
|
||||
|
||||
// Créer la table
|
||||
$targetDb->exec($createTableSql);
|
||||
logOperation("Table $tableName créée avec succès");
|
||||
} else {
|
||||
throw new Exception("Impossible de récupérer la structure de la table source");
|
||||
}
|
||||
}
|
||||
|
||||
// Vider la table cible si l'option est activée
|
||||
if ($truncateTable && $tableExists) {
|
||||
logOperation("Vidage de la table cible $tableName...");
|
||||
$targetDb->exec("TRUNCATE TABLE $tableName");
|
||||
}
|
||||
|
||||
// Construire la requête d'insertion dynamiquement
|
||||
$mapping = $tableMappings[$tableName]['source_to_target'];
|
||||
|
||||
// Récupérer les colonnes de la table cible
|
||||
$stmt = $targetDb->query("DESCRIBE $tableName");
|
||||
$targetColumns = $stmt->fetchAll(PDO::FETCH_COLUMN);
|
||||
|
||||
// Construire les listes de colonnes pour l'insertion
|
||||
$insertColumns = [];
|
||||
$insertPlaceholders = [];
|
||||
$updateClauses = [];
|
||||
|
||||
foreach ($targetColumns as $column) {
|
||||
$insertColumns[] = "`$column`";
|
||||
$insertPlaceholders[] = ":$column";
|
||||
$updateClauses[] = "`$column` = VALUES(`$column`)";
|
||||
}
|
||||
|
||||
$insertColumnsSql = implode(", ", $insertColumns);
|
||||
$insertPlaceholdersSql = implode(", ", $insertPlaceholders);
|
||||
$updateClausesSql = implode(", ", $updateClauses);
|
||||
|
||||
$insertQuery = "INSERT INTO $tableName ($insertColumnsSql) "
|
||||
. "VALUES ($insertPlaceholdersSql) "
|
||||
. "ON DUPLICATE KEY UPDATE $updateClausesSql";
|
||||
|
||||
$insertStmt = $targetDb->prepare($insertQuery);
|
||||
|
||||
// Compteurs
|
||||
$successCount = 0;
|
||||
$errorCount = 0;
|
||||
|
||||
// Traitement de chaque enregistrement
|
||||
foreach ($records as $record) {
|
||||
try {
|
||||
$data = [];
|
||||
|
||||
// Mappage des colonnes selon la configuration
|
||||
foreach ($targetColumns as $targetCol) {
|
||||
// Trouver la colonne source correspondante
|
||||
$sourceCol = array_search($targetCol, $mapping);
|
||||
|
||||
if ($sourceCol !== false) {
|
||||
// La colonne existe dans le mapping
|
||||
$data[$targetCol] = $record[$sourceCol];
|
||||
} elseif (isset($record[$targetCol])) {
|
||||
// La colonne a le même nom dans les deux tables
|
||||
$data[$targetCol] = $record[$targetCol];
|
||||
} else {
|
||||
// Colonne non trouvée, utiliser NULL ou une valeur par défaut
|
||||
$data[$targetCol] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Traitement des champs chiffrés si nécessaire
|
||||
if (isset($tableMappings[$tableName]['encrypted_fields']) && $apiService) {
|
||||
foreach ($tableMappings[$tableName]['encrypted_fields'] as $sourceField => $config) {
|
||||
$targetField = $config['field'];
|
||||
$isSearchable = $config['searchable'];
|
||||
|
||||
if (isset($record[$sourceField]) && !empty($record[$sourceField])) {
|
||||
// Vérifier si le champ est déjà chiffré
|
||||
if (isset($record["encrypted_$sourceField"])) {
|
||||
$data[$targetField] = $record["encrypted_$sourceField"];
|
||||
} else {
|
||||
// Chiffrer la donnée selon qu'elle est recherchable ou non
|
||||
if ($isSearchable) {
|
||||
$data[$targetField] = $apiService->encryptSearchableData($record[$sourceField]);
|
||||
} else {
|
||||
$data[$targetField] = $apiService->encryptData($record[$sourceField]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Gestion spécifique pour certaines tables
|
||||
if ($tableName === 'users') {
|
||||
// Conversion de chk_active (0,1,2) vers is_active (booléen)
|
||||
if (isset($record['chk_active'])) {
|
||||
$data['is_active'] = ($record['chk_active'] > 0) ? 1 : 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Insertion dans la base cible
|
||||
$insertStmt->execute($data);
|
||||
$successCount++;
|
||||
|
||||
// Identifiant pour le log
|
||||
$pkField = $tableMappings[$tableName]['primary_key'];
|
||||
$recordId = $record[$pkField] ?? 'inconnu';
|
||||
|
||||
logOperation("Enregistrement ID $recordId migré avec succès", "INFO");
|
||||
} catch (Exception $e) {
|
||||
$errorCount++;
|
||||
$pkField = $tableMappings[$tableName]['primary_key'];
|
||||
$recordId = $record[$pkField] ?? 'inconnu';
|
||||
|
||||
logOperation("Erreur lors de la migration de l'enregistrement ID $recordId: " . $e->getMessage(), "ERROR");
|
||||
}
|
||||
}
|
||||
|
||||
logOperation("Migration terminée. Succès: $successCount, Erreurs: $errorCount");
|
||||
|
||||
// Fermer le tunnel SSH
|
||||
closeSshTunnel();
|
||||
|
||||
} catch (Exception $e) {
|
||||
logOperation("Erreur critique: " . $e->getMessage(), "ERROR");
|
||||
|
||||
// Fermer le tunnel SSH en cas d'erreur
|
||||
closeSshTunnel();
|
||||
|
||||
exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user