Files
geo/api/scripts/migration2/php/lib/DataMigrator.php
pierre 2f5946a184 feat: Version 3.5.2 - Configuration Stripe et gestion des immeubles
- Configuration complète Stripe pour les 3 environnements (DEV/REC/PROD)
  * DEV: Clés TEST Pierre (mode test)
  * REC: Clés TEST Client (mode test)
  * PROD: Clés LIVE Client (mode live)
- Ajout de la gestion des bases de données immeubles/bâtiments
  * Configuration buildings_database pour DEV/REC/PROD
  * Service BuildingService pour enrichissement des adresses
- Optimisations pages et améliorations ergonomie
- Mises à jour des dépendances Composer
- Nettoyage des fichiers obsolètes

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-09 18:26:27 +01:00

177 lines
5.2 KiB
PHP

<?php
/**
* Classe abstraite de base pour tous les migrators
*
* Fournit les méthodes communes pour migrer des données d'une table
*/
abstract class DataMigrator
{
protected $connection;
protected $logger;
protected $sourceDb;
protected $targetDb;
/**
* Constructeur
*
* @param DatabaseConnection $connection Connexion aux bases
* @param MigrationLogger $logger Logger
*/
public function __construct(DatabaseConnection $connection, MigrationLogger $logger)
{
$this->connection = $connection;
$this->logger = $logger;
$this->sourceDb = $connection->getSourceDb();
$this->targetDb = $connection->getTargetDb();
}
/**
* Méthode principale de migration (à implémenter dans chaque migrator)
*
* @param int|null $entityId ID de l'entité à migrer (null = toutes)
* @param bool $deleteBefore Supprimer les données existantes avant migration
* @return array ['success' => int, 'errors' => int]
*/
abstract public function migrate(?int $entityId = null, bool $deleteBefore = false): array;
/**
* Retourne le nom de la table gérée par ce migrator
*/
abstract public function getTableName(): string;
/**
* Supprime les données d'une entité dans la cible
* À surcharger si la logique de suppression est spécifique
*
* @param int $entityId ID de l'entité
* @return int Nombre de lignes supprimées
*/
protected function deleteEntityData(int $entityId): int
{
$table = $this->getTableName();
try {
// Par défaut: suppression simple avec fk_entite
$stmt = $this->targetDb->prepare("DELETE FROM $table WHERE fk_entite = ?");
$stmt->execute([$entityId]);
$deleted = $stmt->rowCount();
if ($deleted > 0) {
$this->logger->debug(" Supprimé $deleted ligne(s) de $table pour entité #$entityId");
}
return $deleted;
} catch (PDOException $e) {
$this->logger->warning(" Erreur suppression $table: " . $e->getMessage());
return 0;
}
}
/**
* Compte les lignes dans la source
*
* @param int|null $entityId ID de l'entité (null = toutes)
* @return int Nombre de lignes
*/
protected function countSourceRows(?int $entityId = null): int
{
return $this->connection->countSourceRows($this->getTableName(), $entityId);
}
/**
* Compte les lignes dans la cible
*
* @param int|null $entityId ID de l'entité (null = toutes)
* @return int Nombre de lignes
*/
protected function countTargetRows(?int $entityId = null): int
{
return $this->connection->countTargetRows($this->getTableName(), $entityId);
}
/**
* Log le début de la migration d'une table
*/
protected function logStart(?int $entityId = null): void
{
$table = $this->getTableName();
$entityStr = $entityId ? " pour entité #$entityId" : " (toutes les entités)";
$this->logger->info("🔄 Migration de $table{$entityStr}...");
}
/**
* Log la fin de la migration avec statistiques
*
* @param int $success Nombre de succès
* @param int $errors Nombre d'erreurs
* @param int|null $entityId ID de l'entité
*/
protected function logEnd(int $success, int $errors, ?int $entityId = null): void
{
$table = $this->getTableName();
$sourceCount = $this->countSourceRows($entityId);
$targetCount = $this->countTargetRows($entityId);
$diff = $targetCount - $sourceCount;
$diffStr = $diff >= 0 ? "+$diff" : "$diff";
if ($errors > 0) {
$this->logger->warning(" ⚠️ $table: $success succès, $errors erreurs");
} else {
$this->logger->success("$table: $success enregistrement(s) migré(s)");
}
$this->logger->info(" 📊 SOURCE: $sourceCount → CIBLE: $targetCount (différence: $diffStr)");
}
/**
* Exécute une requête INSERT avec ON DUPLICATE KEY UPDATE
*
* @param string $insertSql SQL d'insertion
* @param array $data Données à insérer
* @return bool True si succès
*/
protected function insertOrUpdate(string $insertSql, array $data): bool
{
try {
$stmt = $this->targetDb->prepare($insertSql);
$stmt->execute($data);
return true;
} catch (PDOException $e) {
$this->logger->debug(" Erreur INSERT: " . $e->getMessage());
return false;
}
}
/**
* Démarre une transaction sur la cible
*/
protected function beginTransaction(): void
{
if (!$this->targetDb->inTransaction()) {
$this->targetDb->beginTransaction();
}
}
/**
* Commit la transaction
*/
protected function commit(): void
{
if ($this->targetDb->inTransaction()) {
$this->targetDb->commit();
}
}
/**
* Rollback la transaction
*/
protected function rollback(): void
{
if ($this->targetDb->inTransaction()) {
$this->targetDb->rollBack();
}
}
}