diff --git a/config/module.config.php b/config/module.config.php index 62eb5b98a8d7bcc95ef4b8299ff70edf1c3cc0ab..6728db754d26922f5bef04b046f276e0c7f4feaa 100644 --- a/config/module.config.php +++ b/config/module.config.php @@ -21,6 +21,8 @@ return [ 'dir' => 'data/ddl', 'columns_positions_file' => 'data/ddl_columns_pos.php', 'filters' => [], + 'update-bdd-filters' => [], + 'update-ddl-filters' => [], ], 'data' => [ diff --git a/src/Bdd.php b/src/Bdd.php index 46d9d2309fdb89af1f16015419a053a87e4a2df0..f72df18378d0a45fd61416796ceaf709916694a5 100644 --- a/src/Bdd.php +++ b/src/Bdd.php @@ -498,12 +498,50 @@ class Bdd + public function getFiltersForUpdateBdd(Ddl $ddl): DdlFilters + { + $filters = new DdlFilters(); + $filters->addArray($ddl->getOption(Ddl::OPTION_FILTERS)); + $filters->addArray($ddl->getOption(Ddl::OPTION_UPDATE_BDD_FILTERS)); + $filters->setExplicit(true); + + // On ajouter toute la DDL qu'on donne en référence + $filters->addDdl($ddl); + + // On ajoute toutes les dépendances des tables qu'on a inclu dans la DDL au cas où elles ne seraient pas listées + $filters->addTablesDeps($this); + + return $filters; + } + + + + public function getFiltersForUpdateDdl(): DdlFilters + { + $filters = new DdlFilters(); + $filters->addArray($this->getOption(self::OPTION_DDL.'/'.Ddl::OPTION_FILTERS)); + $filters->addArray($this->getOption(self::OPTION_DDL.'/'.Ddl::OPTION_UPDATE_DDL_FILTERS)); + + return $filters; + } + + + + public function getNewDdl(): Ddl + { + $ddl = new Ddl(); + $ddl->setOptions($this->getOption(self::OPTION_DDL, [])); + + return $ddl; + } + + + public function getDdl(DdlFilters|array $filters = []): Ddl { $this->logBegin("Récupération de la DDL"); $filters = DdlFilters::normalize($filters); - $ddl = new Ddl(); - $ddl->setOptions($this->getOption(self::OPTION_DDL, [])); + $ddl = $this->getNewDdl(); $managers = $this->managerList(); foreach ($managers as $type => $libelle) { if (!($filters->isExplicit() && $filters->get($type)->isEmpty())) { @@ -523,8 +561,7 @@ class Bdd public function getRefDdl(): Ddl { - $ddl = new Ddl(); - $ddl->setOptions($this->getOption(self::OPTION_DDL, [])); + $ddl = $this->getNewDdl(); $ddl->loadFromDir(); return $ddl; diff --git a/src/Command/InstallBddCommand.php b/src/Command/InstallBddCommand.php index 69ef2ccaeb1da62c6af449f4b0afd8b3c0266859..ddb028c1eeb8bb82557bb39cfe86455391d39723 100644 --- a/src/Command/InstallBddCommand.php +++ b/src/Command/InstallBddCommand.php @@ -26,10 +26,10 @@ class InstallBddCommand extends Command $io->title('Installation de la base de données'); - // Mise ne place des objets + // Mise en place des objets try { - $ref = $bdd->getRefDdl(); - $bdd->create($ref); + $ddl = $bdd->getRefDdl(); + $bdd->create($ddl); $io->success('Objets en place'); } catch (\Throwable $e) { $io->error($e->getMessage()); diff --git a/src/Command/UpdateBddCommand.php b/src/Command/UpdateBddCommand.php index 59ea4b9c57504135f8be2760690f95500b9a5b80..451603fe257f0d0153b20cea59dfdbc63224552b 100644 --- a/src/Command/UpdateBddCommand.php +++ b/src/Command/UpdateBddCommand.php @@ -26,39 +26,16 @@ class UpdateBddCommand extends Command $io->title('Mise à jour de la base de données'); - $ref = $bdd->getRefDdl(); - - // Construction de la config de DDL pour filtrer - $filters = []; - foreach ($ref as $ddlClass => $objects) { - foreach ($objects as $object => $objectDdl) { - $filters[$ddlClass]['includes'][] = $object; - } - } - - $tablesDep = [ - Ddl::INDEX, - Ddl::PRIMARY_CONSTRAINT, - Ddl::REF_CONSTRAINT, - Ddl::UNIQUE_CONSTRAINT, - ]; - - foreach ($tablesDep as $tableDep) { - $objects = $bdd->manager($tableDep)->get(); - foreach ($objects as $obj) { - if (in_array($obj['table'], $filters['table']['includes'])) { - $filters[$tableDep]['includes'][] = $obj['name']; - } - } - } + $ddl = $bdd->getRefDdl(); + $filters = $bdd->getFiltersForUpdateBdd($ddl); // Initialisation et lancement de la pré-migration - //$mm = new MigrationManager($oa, $ref, $filters); + //$mm = new MigrationManager($oa, $ddl, $filters); //$mm->migration('before'); try { - $bdd->alter($ref, $filters, true); + $bdd->alter($ddl, $filters, true); $io->success('Objets à jour'); } catch (\Throwable $e) { $io->error($e->getMessage()); @@ -66,7 +43,7 @@ class UpdateBddCommand extends Command // Mise à jour des séquences - $bdd->majSequences($ref); + $bdd->majSequences($ddl); // Mise à jour des données diff --git a/src/Command/UpdateDdlCommand.php b/src/Command/UpdateDdlCommand.php index d485c463214d8ab9971f8759ebcd13a32770c9f1..ae127d8e97cb3230b4d8272083e53e16a2175431 100644 --- a/src/Command/UpdateDdlCommand.php +++ b/src/Command/UpdateDdlCommand.php @@ -22,12 +22,10 @@ class UpdateDdlCommand extends Command $io = new SymfonyStyle($input, $output); $bdd = $this->getBdd()->setLogger($io); - $filters = [ - ]; - $io->title('Génération de la DDL à partir de la base de données'); try { + $filters = $bdd->getFiltersForUpdateDdl(); $ddl = $bdd->getDdl($filters); $ddl->saveToDir(); $io->success('DDL mise à jour'); diff --git a/src/Ddl/Ddl.php b/src/Ddl/Ddl.php index 582da1e115fc0230fb679e086f66f9ddc14829f7..f6d35721a7a68dade6add6da14c357b63d9954b0 100644 --- a/src/Ddl/Ddl.php +++ b/src/Ddl/Ddl.php @@ -27,6 +27,9 @@ class Ddl implements Iterator, ArrayAccess const OPTION_DIR = 'dir'; const OPTION_COLUMNS_POSITIONS_FILE = 'columns_positions_file'; + const OPTION_FILTERS = 'filters'; + const OPTION_UPDATE_BDD_FILTERS = 'update-bdd-filters'; + const OPTION_UPDATE_DDL_FILTERS = 'update-ddl-filters'; protected array $data = []; @@ -436,7 +439,7 @@ class Ddl implements Iterator, ArrayAccess throw new \Exception('Un répertoire doit être spécifié pour charger la DDL'); } - if (!str_ends_with($dir, '/')){ + if (!str_ends_with($dir, '/')) { $dir .= '/'; } @@ -486,12 +489,12 @@ class Ddl implements Iterator, ArrayAccess $data = scandir($dir . $type); foreach ($data as $name) { if ($name != '.' && $name != '..') { - $def = file_get_contents($dir . $type . '/' . $name); - $name = substr($name, 0, -4); + $def = file_get_contents($dir . $type . '/' . $name); + $name = substr($name, 0, -4); if (str_contains($name, '.')) { [$schema, $vmname] = Util::explodedFullObjectName($name); $this->data[$type][$name] = ['schema' => $schema, 'name' => $vmname, 'definition' => $def]; - }else{ + } else { $this->data[$type][$name] = ['name' => $name, 'definition' => $def]; } diff --git a/src/Ddl/DdlFilter.php b/src/Ddl/DdlFilter.php index ba73b0ea655bd671e1730427f989f988f345a122..73dbfc2418479838f65521209eb7276726afbf74 100644 --- a/src/Ddl/DdlFilter.php +++ b/src/Ddl/DdlFilter.php @@ -65,6 +65,13 @@ class DdlFilter implements \ArrayAccess + public function hasInclude(string $include): bool + { + return in_array($include, $this->includes); + } + + + public function getExcludes(): array { return $this->excludes; @@ -96,6 +103,13 @@ class DdlFilter implements \ArrayAccess + public function hasExclude(string $exclude): bool + { + return in_array($exclude, $this->excludes); + } + + + public function toArray(): array { return [ @@ -120,7 +134,7 @@ class DdlFilter implements \ArrayAccess if (null === $filter) { $filter = []; - }elseif(is_string($filter)){ + } elseif (is_string($filter)) { $filter = [$filter]; } @@ -165,11 +179,11 @@ class DdlFilter implements \ArrayAccess $i++; if ($schemaColName && $includeSchema) { - $f[] = "OR ($schemaColName LIKE :includesc$i AND $colName LIKE :includeobj$i)"; - $p["includesc$i"] = $includeSchema; + $f[] = "OR ($schemaColName LIKE :includesc$i AND $colName LIKE :includeobj$i)"; + $p["includesc$i"] = $includeSchema; $p["includeobj$i"] = $includeObject; } else { - $f[] = "OR $colName LIKE :include$i"; + $f[] = "OR $colName LIKE :include$i"; $p["include$i"] = $includeObject; } } @@ -188,11 +202,11 @@ class DdlFilter implements \ArrayAccess $i++; if ($schemaColName && $excludeSchema) { - $f[] = "OR ($schemaColName LIKE :excludesc$i AND $colName LIKE :excludeobj$i)"; - $p["excludesc$i"] = $excludeSchema; + $f[] = "OR ($schemaColName LIKE :excludesc$i AND $colName LIKE :excludeobj$i)"; + $p["excludesc$i"] = $excludeSchema; $p["excludeobj$i"] = $excludeObject; } else { - $f[] = "OR $colName LIKE :exclude$i"; + $f[] = "OR $colName LIKE :exclude$i"; $p["exclude$i"] = $excludeObject; } } diff --git a/src/Ddl/DdlFilters.php b/src/Ddl/DdlFilters.php index 1ea1b7ed01cd12d70cc2414bb728b2be408caf5d..acb0fd63f74d07c5cf8a3a0406985b357699f6c3 100644 --- a/src/Ddl/DdlFilters.php +++ b/src/Ddl/DdlFilters.php @@ -2,6 +2,9 @@ namespace Unicaen\BddAdmin\Ddl; +use Unicaen\BddAdmin\Bdd; +use Unicaen\BddAdmin\Util; + class DdlFilters implements \Iterator, \ArrayAccess { const EXPLICIT = 'explicit'; @@ -65,13 +68,22 @@ class DdlFilters implements \Iterator, \ArrayAccess { $this->setExplicit(true); - $filters = []; foreach ($ddl as $ddlClass => $objects) { foreach ($objects as $object => $objectDdl) { - $filters[$ddlClass][DdlFilter::INCLUDES][] = $object; + $ddlFilter = $this->get($ddlClass); + if (!$ddlFilter->hasInclude($object)) { + $ddlFilter->addInclude($object); + } } } + return $this; + } + + + + public function addTablesDeps(Bdd $bdd): self + { $tablesDep = [ Ddl::INDEX, Ddl::PRIMARY_CONSTRAINT, @@ -79,17 +91,25 @@ class DdlFilters implements \Iterator, \ArrayAccess Ddl::UNIQUE_CONSTRAINT, ]; + $ddlTableFilter = $this->get(Ddl::TABLE); + foreach ($tablesDep as $tableDep) { - $objects = $ddl->get($tableDep); + $ddlFilter = $this->get($tableDep); + + $objects = $bdd->manager($tableDep)->get(); foreach ($objects as $obj) { - if (is_array($obj) && in_array($obj['table'], $filters['table'][DdlFilter::INCLUDES])) { - $filters[$tableDep][DdlFilter::INCLUDES][] = $obj['name']; + if (is_array($obj)){ + $tableName = Util::fullObjectName($obj['schema'] ?? null, $obj['table']); + if ($ddlTableFilter->hasInclude($tableName)) { + $objectName = Util::fullObjectName($obj['schema'] ?? null, $obj['name']); + if (!$ddlFilter->hasInclude($objectName)) { + $ddlFilter->addInclude($objectName); + } + } } } } - $this->addArray($filters); - return $this; }