Skip to content
Snippets Groups Projects
Select Git revision
  • 097d7f7686533e1c18c6ea672bc23e8c5bf42ca7
  • master default protected
  • ll-workflow
  • b24
  • alc-scindage-donnees-pj
  • FJ_LL_Tbl_Contrat
  • alc-docker-node
  • ll-apiplatform
  • php84
  • ll-rgpd
  • b23
  • alc-filtre-type-intervenant
  • ll-sans-mdb5
  • formules-ancienne-infra
  • ll-formules
  • alc-intervenant-dmep
  • ll-suppr-v_vol-s
  • b20
  • ll-postgresql
  • b23.0.1
  • b22
  • 24.8
  • 24.7
  • 24.6
  • 24.5
  • 24.4
  • 24.3
  • 24.2
  • 24.1
  • 24.0
  • 23.15
  • 24.0-beta19
  • 24.0-beta18
  • 24.0-beta17
  • 24.0-beta16
  • 24.0-beta15
  • 24.0-beta14
  • 24.0-beta13
  • 23.14
  • 24.0-beta12
  • 24.0-beta11
41 results

GenDbStructure.php

Blame
  • Code owners
    Assign users and groups as approvers for specific file changes. Learn more.
    RunSQLProcess.php 5.17 KiB
    <?php
    
    namespace UnicaenApp\Service\SQL;
    
    use Doctrine\DBAL\Connection;
    use Doctrine\DBAL\DBALException;
    use Exception;
    use UnicaenApp\Exception\RuntimeException;
    use Zend\Log\Logger;
    use Zend\Log\LoggerAwareTrait;
    
    class RunSQLProcess
    {
        use LoggerAwareTrait;
    
        /**
         * @var string
         */
        private $scriptPath;
    
        /**
         * @var string
         */
        private $logFilePath;
    
        /**
         * @var Connection
         */
        private $connection;
    
        /**
         * @var RunSQLQueryStack
         */
        private $queryStack;
    
        /**
         * @param string $scriptPath
         * @return self
         */
        public function setScriptPath($scriptPath)
        {
            $this->scriptPath = $scriptPath;
    
            return $this;
        }
    
        /**
         * @param Connection $connection
         * @return RunSQLProcess
         */
        public function setConnection(Connection $connection)
        {
            $this->connection = $connection;
    
            return $this;
        }
    
        /**
         * @param null|string $logFilePath
         * @return self
         */
        public function setLogFilePath($logFilePath = null)
        {
            $this->logFilePath = $logFilePath;
    
            return $this;
        }
    
        /**
         * Exécute dans la transaction courante toutes les instructions d'un script SQL.
         *
         * @return RunSQLResult
         */
        public function executeScript()
        {
            $this->validateScriptPath();
    
            $queries = $this->extractQueriesFromScript();
    
            $this->logger->info("+ Exécution du script '$this->scriptPath'.");
            $this->logger->info(sprintf("'--> Requêtes trouvées : %d", count($queries)));
    
            $result = $this->executeQueries($queries);
    
            $logFilePath = $this->logQueries();
            $this->logger->info("'--> Logs : " . $logFilePath);
    
            return $result;
        }
    
        /**
         * Exécute dans la transaction courante toutes les instructions d'un script SQL.
         *
         * @param string $query
         * @return RunSQLResult
         */
        public function executeQuery($query)
        {
            $this->logger->info("+ Exécution d'une requête.");
    
            $result = $this->executeQueries([$query]);
    
            $logFilePath = $this->logQueries();
            $this->logger->info("'--> Logs : " . $logFilePath);
    
            return $result;
        }
    
        private function validateScriptPath()
        {
            if (is_dir($this->scriptPath)) {
                throw new RuntimeException("Le fichier '$this->scriptPath' spécifié est un répertoire");
            }
            if (!is_readable($this->scriptPath)) {
                throw new RuntimeException("Le fichier '$this->scriptPath' n'est pas accessible");
            }
        }
    
        /**
         * Extrait les requêtes contenues dans le script.
         *
         * @return string[]
         */
        protected function extractQueriesFromScript()
        {
            $parts = preg_split("#^/$#m", file_get_contents($this->scriptPath));
            $queries = array_filter(array_map('trim', $parts));
    
            if (count($queries) === 0) {
                throw new RuntimeException("Aucune requête trouvée dans le script '$this->scriptPath'");
            }
    
            return $queries;
        }
    
        /**
         * Exécute dans la transaction courante les requêtes spécifiées.
         *
         * @param string[] $queries
         * @return RunSQLResult
         */
        private function executeQueries($queries)
        {
            $result = new RunSQLResult();
            $result->attachLogger($this->logger);
            $result->setIsSuccess(true);
    
            $this->queryStack = new RunSQLQueryStack();
    
            try {
                foreach ($queries as $q) {
                    $this->queryStack->startQuery($q);
                    $this->connection->executeQuery($q);
                    $this->queryStack->stopQuery();
                }
            } catch (DBALException $e) {
                $result->setIsSuccess(false);
                $result->setException($e);
    
                $this->queryStack->stopQueryWithException($e);
            }
    
            $result->setEndMicrotime();
    
            return $result;
        }
    
        /**
         * @return string
         */
        private function logQueries()
        {
            $logFilePath = $this->generateLogFilePath();
    
            $logger = new Logger();
            $logger->addWriter('stream', null, ['stream' => $logFilePath]);
    
            foreach ($this->queryStack->getQueries() as $query) {
                $logger->info("Requête : " . $query['sql']);
                if (isset($query['exception'])) {
                    /** @var Exception $exception */
                    $exception = $query['exception'];
                    $logger->info($exception->getMessage());
                    $logger->info($exception->getTraceAsString());
                }
                $logger->info("Temps d'exécution : " . $query['executionMS'] . " sec");
                $logger->info("---------------------------------------------------------------------------------------");
            }
    
            return $logFilePath;
        }
    
        /**
         * @return string
         */
        private function generateLogFilePath()
        {
            if ($this->logFilePath !== null) {
                return $this->logFilePath;
            }
    
            if ($this->scriptPath) {
                $this->logFilePath = sys_get_temp_dir() . '/' . basename($this->scriptPath) . '.log';
            } else {
                $this->logFilePath = sys_get_temp_dir() . '/' . uniqid('unicaen-app-run-sql-') . '.log';
            }
    
            return $this->logFilePath;
        }
    }