diff --git a/config/module.config.php b/config/module.config.php index bb7f7380ed94e5d3d05b031256053c394672fb6f..62eb5b98a8d7bcc95ef4b8299ff70edf1c3cc0ab 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -20,16 +20,20 @@ return [ 'ddl' => [ 'dir' => 'data/ddl', 'columns_positions_file' => 'data/ddl_columns_pos.php', + 'filters' => [], ], 'data' => [ - 'sources' => [], - 'actions' => [], + 'actions' => [ + 'install' => 'Insertion des données', + 'update' => 'Contrôle et mise à jour des données', + ], 'config' => [], // configuration par tables + 'sources' => [], ], 'migration' => [ - 'dir' => 'Application/src/Migration', + 'dir' => null, ], 'id_column' => 'id', @@ -54,17 +58,24 @@ return [ 'service_manager' => [ 'factories' => [ - Bdd::class => BddFactory::class, - Command\UpdateBddCommand::class => Command\UpdateBddCommandFactory::class, - Command\UpdateDdlCommand::class => Command\UpdateDdlCommandFactory::class, + Bdd::class => BddFactory::class, + Command\InstallBddCommand::class => Command\CommandFactory::class, + Command\UpdateBddCommand::class => Command\CommandFactory::class, + Command\UpdateDdlCommand::class => Command\CommandFactory::class, + Command\UpdateDataCommand::class => Command\CommandFactory::class, + Command\ClearBddCommand::class => Command\CommandFactory::class, ], ], 'laminas-cli' => [ 'commands' => [ - 'bddadmin:update-bdd' => Command\UpdateBddCommand::class, - 'bddadmin:update-ddl' => Command\UpdateDdlCommand::class, + 'bddadmin:install-bdd' => Command\InstallBddCommand::class, + 'bddadmin:update-bdd' => Command\UpdateBddCommand::class, + 'bddadmin:clear-bdd' => Command\ClearBddCommand::class, + 'bddadmin:update-ddl' => Command\UpdateDdlCommand::class, + 'bddadmin:update-data' => Command\UpdateDataCommand::class, + ], ], ]; \ No newline at end of file diff --git a/src/Bdd.php b/src/Bdd.php index b8af3cab41a5a05d6f563be35e9d6f133d2dd55e..46d9d2309fdb89af1f16015419a053a87e4a2df0 100644 --- a/src/Bdd.php +++ b/src/Bdd.php @@ -185,7 +185,7 @@ class Bdd if ($this->hasConnection($connection)) { $this->bdds[$connection] = new self($this->getOptions(), $connection); } else { - throw new \Exception('La connexion "' . $connection . '" n\'est pas présente en config, rubrique unicaen-bddadmin/'.self::OPTION_CONNECTION); + throw new \Exception('La connexion "' . $connection . '" n\'est pas présente en config, rubrique unicaen-bddadmin/' . self::OPTION_CONNECTION); } } @@ -285,14 +285,14 @@ class Bdd public function selectOne(string $sql, array $params = [], string $column = null, array $options = []): mixed { $options['fetch'] = self::FETCH_ONE; - $res = $this->select($sql, $params, $options); + $res = $this->select($sql, $params, $options); if (empty($res)) return null; if (is_array($res) && !empty($column)) { - if (!isset($res[$column])){ + if (!isset($res[$column])) { $column = strtolower($column); - $res = array_change_key_case($res, CASE_LOWER); + $res = array_change_key_case($res, CASE_LOWER); } return $res[$column]; @@ -599,7 +599,6 @@ class Bdd public function create(Bdd|Ddl|array $ddl, DdlFilters|array $filters = []): void { - $this->logBegin('Mise en place de la base de données'); $filters = DdlFilters::normalize($filters); if ($ddl instanceof self) { $ddl = $ddl->getDdl($filters); @@ -632,14 +631,12 @@ class Bdd } } $this->compilerTout(); - $this->logEnd("Base de données créée"); } public function alter(Bdd|Ddl|array $ddl, DdlFilters|array $filters = []): void { - $this->logBegin('Application des changements sur la BDD'); $filters = DdlFilters::normalize($filters); if ($ddl instanceof self) { @@ -680,20 +677,18 @@ class Bdd $this->logEnd(); } } + } } - + $this->logEnd(); $this->compilerTout(); $this->migration()->migration('after'); - $this->logEnd('Changements appliqués'); - $this->majSequences($ddl); } public function drop(DdlFilters|array $filters = []): void { - $this->logBegin('Suppression de la base de données'); $filters = DdlFilters::normalize($filters); foreach ($this->changements as $changement => $label) { @@ -721,7 +716,7 @@ class Bdd } } } - $this->logEnd("Base de données vide"); + $this->logEnd(); } @@ -848,13 +843,22 @@ class Bdd public function compilerTout(): array { - $this->logBegin("Compilation de tous les objets de la BDD"); - $errors = []; - $compileTypes = [Ddl::PACKAGE, Ddl::VIEW, Ddl::TRIGGER]; + $managers = []; foreach ($compileTypes as $compileType) { $manager = $this->manager($compileType); if ($manager instanceof CompilableInterface) { + $managers[] = $manager; + } + } + + $errors = []; + + if ($managers) { + + $this->logBegin("Compilation de tous les objets de la BDD"); + + foreach ($managers as $manager) { $list = $manager->getList(); foreach ($list as $name) { try { @@ -866,8 +870,9 @@ class Bdd } } } + $this->logEnd("Fin de la compilation"); + } - $this->logEnd("Fin de la compilation"); return $errors; } diff --git a/src/BddFactory.php b/src/BddFactory.php index 5c508439e5fd87290f84545282796498fabcc1f8..e4c275b2ac35b131ea713ee863af71ccc77f51d6 100644 --- a/src/BddFactory.php +++ b/src/BddFactory.php @@ -3,6 +3,7 @@ namespace Unicaen\BddAdmin; use Psr\Container\ContainerInterface; +use Unicaen\BddAdmin\Data\DataManager; /** * Description of BddFactory @@ -23,8 +24,24 @@ class BddFactory { $config = $container->get('config')['unicaen-bddadmin']; - $bdd = new Bdd($config); + $bdd = new Bdd($this->prepareConfig($config, $container)); return $bdd; } + + + + public function prepareConfig(array $config, ContainerInterface $container): array + { + if (isset($config[Bdd::OPTION_DATA][DataManager::OPTION_SOURCES])){ + $sources = &$config[Bdd::OPTION_DATA][DataManager::OPTION_SOURCES]; + foreach( $sources as $index => $source){ + if ($container->has($source)){ + $sources[$index] = $container->get($source); + } + } + } + + return $config; + } } \ No newline at end of file diff --git a/src/Command/ClearBddCommand.php b/src/Command/ClearBddCommand.php new file mode 100644 index 0000000000000000000000000000000000000000..ecbe5fdc2bba3982a8d07ee947fe42d08aba9f5d --- /dev/null +++ b/src/Command/ClearBddCommand.php @@ -0,0 +1,38 @@ +<?php + +namespace Unicaen\BddAdmin\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Unicaen\BddAdmin\BddAwareTrait; +use Unicaen\BddAdmin\Data\DataManager; +use Unicaen\BddAdmin\Ddl\Ddl; + +/** + * Description of ClearBddCommand + * + * @author Laurent Lécluse <laurent.lecluse at unicaen.fr> + */ +class ClearBddCommand extends Command +{ + use BddAwareTrait; + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $bdd = $this->getBdd()->setLogger($io); + + $io->title('Vidage complet de la base de données'); + + try { + $bdd->drop(); + $io->success('Base de données vidée complètement'); + } catch (\Throwable $e) { + $io->error($e->getMessage()); + } + + return Command::SUCCESS; + } +} \ No newline at end of file diff --git a/src/Command/UpdateBddCommandFactory.php b/src/Command/CommandFactory.php similarity index 72% rename from src/Command/UpdateBddCommandFactory.php rename to src/Command/CommandFactory.php index 4b5ef7dc3dd9cb67cb2caa07fd7f986bbe8da14a..f63218f54057703938005096d3b092beb2e43b7b 100644 --- a/src/Command/UpdateBddCommandFactory.php +++ b/src/Command/CommandFactory.php @@ -7,11 +7,11 @@ use Unicaen\BddAdmin\Bdd; /** - * Description of UpdateBddCommandFactory + * Description of CommandFactory * * @author Laurent Lécluse <laurent.lecluse at unicaen.fr> */ -class UpdateBddCommandFactory +class CommandFactory { /** @@ -19,11 +19,11 @@ class UpdateBddCommandFactory * @param string $requestedName * @param array|null $options * - * @return UpdateBddCommand + * @return InstallBddCommand */ - public function __invoke(ContainerInterface $container, $requestedName, $options = null): UpdateBddCommand + public function __invoke(ContainerInterface $container, $requestedName, $options = null) { - $command = new UpdateBddCommand; + $command = new $requestedName; $command->setBdd($container->get(Bdd::class)); return $command; diff --git a/src/Command/InstallBddCommand.php b/src/Command/InstallBddCommand.php new file mode 100644 index 0000000000000000000000000000000000000000..69ef2ccaeb1da62c6af449f4b0afd8b3c0266859 --- /dev/null +++ b/src/Command/InstallBddCommand.php @@ -0,0 +1,51 @@ +<?php + +namespace Unicaen\BddAdmin\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Unicaen\BddAdmin\BddAwareTrait; +use Unicaen\BddAdmin\Data\DataManager; +use Unicaen\BddAdmin\Ddl\Ddl; + +/** + * Description of InstallBddCommand + * + * @author Laurent Lécluse <laurent.lecluse at unicaen.fr> + */ +class InstallBddCommand extends Command +{ + use BddAwareTrait; + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $bdd = $this->getBdd()->setLogger($io); + + $io->title('Installation de la base de données'); + + // Mise ne place des objets + try { + $ref = $bdd->getRefDdl(); + $bdd->create($ref); + $io->success('Objets en place'); + } catch (\Throwable $e) { + $io->error($e->getMessage()); + } + + if (!empty($bdd->data()->getSources())) { + // Installation des données + $io->title('Insertion du jeu de données données'); + try { + $bdd->data()->run(DataManager::ACTION_INSTALL); + $io->success('Données écrites'); + } catch (\Throwable $e) { + $io->error($e->getMessage()); + } + } + + return Command::SUCCESS; + } +} \ No newline at end of file diff --git a/src/Command/UpdateBddCommand.php b/src/Command/UpdateBddCommand.php index 7e75b266096f80a9e0c91d853aa1dfcdc5881e5b..59ea4b9c57504135f8be2760690f95500b9a5b80 100644 --- a/src/Command/UpdateBddCommand.php +++ b/src/Command/UpdateBddCommand.php @@ -7,6 +7,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Unicaen\BddAdmin\BddAwareTrait; +use Unicaen\BddAdmin\Data\DataManager; use Unicaen\BddAdmin\Ddl\Ddl; /** @@ -17,14 +18,13 @@ use Unicaen\BddAdmin\Ddl\Ddl; class UpdateBddCommand extends Command { use BddAwareTrait; - + protected function execute(InputInterface $input, OutputInterface $output): int { - $io = new SymfonyStyle($input, $output); + $io = new SymfonyStyle($input, $output); $bdd = $this->getBdd()->setLogger($io); $io->title('Mise à jour de la base de données'); - $io->info('Mise à jour des définitions de la base de données. Merci de patienter ...'); $ref = $bdd->getRefDdl(); @@ -57,8 +57,12 @@ class UpdateBddCommand extends Command //$mm->migration('before'); - // Mise à jour de la BDD (structures) - $bdd->alter($ref, $filters, true); + try { + $bdd->alter($ref, $filters, true); + $io->success('Objets à jour'); + } catch (\Throwable $e) { + $io->error($e->getMessage()); + } // Mise à jour des séquences @@ -66,10 +70,15 @@ class UpdateBddCommand extends Command // Mise à jour des données - //$bdd->logBegin('Contrôle et mise à jour des données'); - //$bdd->dataUpdater()->run('update'); - //$bdd->logEnd('Données à jour'); - + if (!empty($bdd->data()->getSources())) { + $io->title('Contrôle et mise à jour des données'); + try { + $bdd->data()->run(DataManager::ACTION_UPDATE); + $io->success('Données à jour'); + } catch (\Throwable $e) { + $io->error($e->getMessage()); + } + } // Post-migration diff --git a/src/Command/UpdateDataCommand.php b/src/Command/UpdateDataCommand.php new file mode 100644 index 0000000000000000000000000000000000000000..4913b9c43169cd3d502e0f20483ad7ed41220b44 --- /dev/null +++ b/src/Command/UpdateDataCommand.php @@ -0,0 +1,41 @@ +<?php + +namespace Unicaen\BddAdmin\Command; + +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Unicaen\BddAdmin\BddAwareTrait; +use Unicaen\BddAdmin\Ddl\Ddl; + +/** + * Description of UpdateDataCommand + * + * @author Laurent Lécluse <laurent.lecluse at unicaen.fr> + */ +class UpdateDataCommand extends Command +{ + use BddAwareTrait; + + protected function execute(InputInterface $input, OutputInterface $output): int + { + $io = new SymfonyStyle($input, $output); + $bdd = $this->getBdd()->setLogger($io); + + // Mise à jour des données + if (!empty($bdd->data()->getSources())) { + $io->title('Contrôle et mise à jour des données'); + try { + $bdd->data()->run('update'); + $io->success('Données à jour'); + } catch (\Throwable $e) { + $io->error($e->getMessage()); + } + }else{ + $io->error('Aucune source de donnée fournie'); + } + + return Command::SUCCESS; + } +} \ No newline at end of file diff --git a/src/Command/UpdateDdlCommand.php b/src/Command/UpdateDdlCommand.php index 9fdeecf80a7b4b84a8a23afc6912ca72d9329c09..d485c463214d8ab9971f8759ebcd13a32770c9f1 100644 --- a/src/Command/UpdateDdlCommand.php +++ b/src/Command/UpdateDdlCommand.php @@ -19,7 +19,7 @@ class UpdateDdlCommand extends Command protected function execute(InputInterface $input, OutputInterface $output): int { - $io = new SymfonyStyle($input, $output); + $io = new SymfonyStyle($input, $output); $bdd = $this->getBdd()->setLogger($io); $filters = [ @@ -27,9 +27,13 @@ class UpdateDdlCommand extends Command $io->title('Génération de la DDL à partir de la base de données'); - $ddl = $bdd->getDdl($filters); - - $ddl->saveToDir(); + try { + $ddl = $bdd->getDdl($filters); + $ddl->saveToDir(); + $io->success('DDL mise à jour'); + } catch (\Throwable $e) { + $io->error($e->getMessage()); + } return Command::SUCCESS; } diff --git a/src/Command/UpdateDdlCommandFactory.php b/src/Command/UpdateDdlCommandFactory.php deleted file mode 100644 index c6402da14da5ad5f4613fd8fa64efb8d85e779b5..0000000000000000000000000000000000000000 --- a/src/Command/UpdateDdlCommandFactory.php +++ /dev/null @@ -1,32 +0,0 @@ -<?php - -namespace Unicaen\BddAdmin\Command; - -use Psr\Container\ContainerInterface; -use Unicaen\BddAdmin\Bdd; - - -/** - * Description of UpdateDdlCommandFactory - * - * @author Laurent Lécluse <laurent.lecluse at unicaen.fr> - */ -class UpdateDdlCommandFactory -{ - - - /** - * @param ContainerInterface $container - * @param string $requestedName - * @param array|null $options - * - * @return UpdateBddCommand - */ - public function __invoke(ContainerInterface $container, $requestedName, $options = null): UpdateDdlCommand - { - $command = new UpdateDdlCommand; - $command->setBdd($container->get(Bdd::class)); - - return $command; - } -} \ No newline at end of file diff --git a/src/Data/DataManager.php b/src/Data/DataManager.php index 8e869ca8de49c8d16608b5ee93b1590d936ab5e3..e0b68d7d235a1d5f38544f35f3b127461274448b 100644 --- a/src/Data/DataManager.php +++ b/src/Data/DataManager.php @@ -11,17 +11,15 @@ class DataManager use BddAwareTrait; use OptionsTrait; - private array $config = []; + const OPTION_SOURCES = 'sources'; + const OPTION_ACTIONS = 'actions'; + const OPTION_CONFIG = 'config'; - private array $sources = []; + const ACTION_INSTALL = 'install'; + const ACTION_UPDATE = 'update'; private array $sourcesData = []; - private array $actions = [ - 'install' => 'Insertion des données', - 'update' => 'Contrôle et mise à jour des données', - ]; - public function __construct(Bdd $bdd) @@ -33,15 +31,18 @@ class DataManager public function run(string $action, ?string $table = null): DataManager { - if (!isset($this->actions[$action])) { + if (!$this->hasAction($action)) { throw new \Exception('Action "' . $action . '" inconnue'); } - if ($table && !isset($this->config[$table])) { - throw new \Exception('La table "' . $table . '" n\'est pas de directives de configuration : action impossible à réaliser'); + if ($table && !$this->hasConfig($table)) { + throw new \Exception('La table "' . $table . '" n\'est pas de directives de configuration : action impossible à réaliser'); } - $config = $table ? [$table => $this->config[$table]] : $this->config; + $config = $this->getOption(self::OPTION_CONFIG); + if ($table) { + $config = [$table => $config[$table]]; + } foreach ($config as $table => $config) { $actions = (array)$config['actions']; @@ -63,16 +64,18 @@ class DataManager $idCol = $this->getBdd()->getOption(Bdd::OPTION_ID_COLUMN); - $data = null; - foreach ($this->sources as $i => $source) { - if (is_object($source) && method_exists($source, $table)) { - $data = $source->$table($action); - break; - } + $data = null; + $sources = $this->getSources(); + foreach ($sources as $i => $source) { if (is_array($source) && isset($source[$table])) { $data = $source[$table]; break; } + $methodName = str_replace('.', '_', $table); + if (is_object($source) && method_exists($source, $methodName)) { + $data = $source->$methodName($action); + break; + } if (is_string($source)) { if (!isset($this->sourcesData[$i]) && file_exists($source)) { $this->sourcesData[$i] = require $source; @@ -87,6 +90,9 @@ class DataManager if (null === $data) { throw new \Exception('Données sources introuvables pour la table "' . $table . '"'); } + if (!is_array($data)) { + throw new \Exception('Les données sources de la table "' . $table . '" doivent être présentées sous forme de tableau de lignes, chaque ligne étant un tableau de colonnes'); + } $result = $tableObject->merge( $data, @@ -102,35 +108,17 @@ class DataManager - /** - * @return array - */ public function getConfig(): array { - return $this->config; + return $this->getOption(self::OPTION_CONFIG); } - /** - * @param array $config - * - * @return DataManager - */ - public function setConfig(array $config): DataManager + public function hasConfig(string $tableName): bool { - $this->config = $config; - - return $this; - } - - - - public function addConfig(string $table, array $config): DataManager - { - $this->config[$table] = $config; - - return $this; + $config = $this->getConfig(); + return array_key_exists($tableName, $config); } @@ -140,14 +128,16 @@ class DataManager */ public function getSources(): array { - return $this->sources; + return $this->getOption(self::OPTION_SOURCES); } public function addSource(string|array|object $source): DataManager { - $this->sources[] = $source; + $sources = $this->getSources(); + $sources[] = $source; + $this->setOptions(self::OPTION_SOURCES, $sources); return $this; } @@ -159,14 +149,24 @@ class DataManager */ public function getActions(): array { - return $this->actions; + return $this->getOption(self::OPTION_ACTIONS); + } + + + + public function hasAction(string $action): bool + { + $actions = $this->getActions(); + return array_key_exists($action, $actions); } public function addAction(string $name, string $libelle): DataManager { - $this->actions[$name] = $libelle; + $actions = $this->getActions(); + $actions[$name] = $libelle; + $this->setOptions(self::OPTION_ACTIONS, $actions); return $this; } diff --git a/src/Logger/SymfonyStyleLogger.php b/src/Logger/SymfonyStyleLogger.php index 15307cf664ec0329b0f6f07a2c16674d0b87004e..1177c49d660ffc9feac146aa4b20aac73ec0d6c5 100644 --- a/src/Logger/SymfonyStyleLogger.php +++ b/src/Logger/SymfonyStyleLogger.php @@ -72,7 +72,7 @@ class SymfonyStyleLogger implements LoggerInterface } $this->lastRewrite = false; $this->lastMessage = null; - $this->symfonyStyle->title($title); + $this->symfonyStyle->comment($title); } @@ -82,10 +82,10 @@ class SymfonyStyleLogger implements LoggerInterface if ($this->lastMessage && $this->lastRewrite) { $msg .= str_pad('', strlen($this->lastMessage) - strlen($msg ?? '') + 2); } - if (trim($msg)) { + if ($msg && trim($msg)) { $this->symfonyStyle->comment($msg); } else { - $this->println(''); + $this->println(str_pad(' ', strlen($this->lastMessage ?? ''))); } } diff --git a/src/Table.php b/src/Table.php index fb7261c47f70f965704bc3c3685b5cbada9934a8..f2f74641062f03fe5cf652a31643f97a784f77fc 100644 --- a/src/Table.php +++ b/src/Table.php @@ -390,7 +390,9 @@ class Table $sql = "UPDATE " . $this->name . " SET $dataSql" . $this->makeWhere($where, $options, $params); - return $bdd->exec($sql, $params, $this->makeTypesOptions()); + $bdd->exec($sql, $params, $this->makeTypesOptions()); + + return true; } @@ -400,7 +402,8 @@ class Table $params = []; $sql = "DELETE FROM " . $this->name . $this->makeWhere($where, $options, $params); - return $this->getBdd()->exec($sql, $params); + $this->getBdd()->exec($sql, $params); + return true; } @@ -409,7 +412,8 @@ class Table { $sql = "TRUNCATE TABLE " . $this->name; - return $this->getBdd()->exec($sql); + $this->getBdd()->exec($sql); + return true; }