>> bin/console ot:cron run db-check */ class DbCheck extends BaseCronJob { public const IGNORE_EMPTY_TABLES = [ 'messenger_messages', 'enqueue', 'zzz_.*', 'CycleByEducation', // Table a priori non utilisée 'educationalproject_file', 'ElasticaSynchro', 'Odyssee', 'PeriodNotation', // Table a priori non utilisée 'Presence', 'tag_accessWish', 'tag_control', 'tag_educationNotation', 'tag_educationStudent', 'tag_repair', ]; public function __construct( private readonly EntityManagerInterface $testBackupEntityManager, ) { parent::__construct(); } public function preview(): void { $this->ui->print('No preview available for this job'); } /** * Execute database integrity checks. */ public function execute(): void { $this->logger->info('Démarrage de la vérification de l\'intégrité de la base de données'); $this->logger->info('1. Vérification de la connexion à la base de données'); try { $connection = $this->getDbConnection(); } catch (\Exception $e) { $this->logger->critical($e->getMessage()); return; } $this->logger->info('2. Vérification de l\'intégrité des données'); try { $schemaManager = $connection->createSchemaManager(); $tables = $schemaManager->listTableNames(); $this->logger->debug(sprintf('Nombre total de tables: %d', count($tables))); $emptyTables = []; foreach ($tables as $table) { try { if (preg_match('/^'.implode('|', self::IGNORE_EMPTY_TABLES).'$/', $table)) { $this->logger->debug(sprintf('Table %s: -- ignored --', $table)); continue; } $count = (int) $connection->executeQuery("SELECT COUNT(*) FROM {$table}")->fetchOne(); if (!$count > 0) { $emptyTables[] = $table; } $this->logger->debug(sprintf('Table %s: %d enregistrements', $table, $count)); } catch (\Exception $tableException) { $this->logger->critical(sprintf('Impossible de vérifier la table %s: %s', $table, $tableException->getMessage())); } } if (count($emptyTables) > 0) { $this->logger->critical('%d tables vides détectées sur %d tables au total'); $this->logger->error('Tables vides:'); foreach ($emptyTables as $table) { $this->logger->error('- '.$table); } } else { $this->logger->info('Toutes les tables sont présentes et contiennent des données'); } } catch (\Exception $e) { $this->logger->critical('Erreur lors de la vérification de l\'intégrité des données: '.$e->getMessage()); $this->logger->debug('Stack trace: '.$e->getTraceAsString()); } } /** * Establishes a connection to the database. * * @return Connection the active database connection * * @throws \RuntimeException if the connection could not be established * or if an error occurs during the process */ private function getDbConnection(): Connection { try { /** @var Connection $connection */ $connection = $this->testBackupEntityManager->getConnection(); $connection->connect(); if ($connection->isConnected()) { $this->logger->info('Connexion à la base de données testBackup établie avec succès'); $params = $connection->getParams(); $this->logger->debug(sprintf( 'Paramètres de connexion testBackup: Driver=%s, Host=%s, Port=%s, Database=%s, User=%s', $params['driver'] ?? 'N/A', $params['host'] ?? 'N/A', $params['port'] ?? 'N/A', $params['dbname'] ?? 'N/A', $params['user'] ?? 'N/A' )); } else { throw new \RuntimeException('Impossible de se connecter à la base de données'); } } catch (\Exception $e) { throw new \RuntimeException('Erreur lors de la connexion à la base de données: '.$e->getMessage()); } return $connection; } }