diff --git a/src/UnicaenSynchro/Service/SqlHelper/SqlHelperService.php b/src/UnicaenSynchro/Service/SqlHelper/SqlHelperService.php index 7ca2dd8912f71c97704f64ffb0651465d1293a8c..653138acab4ccf486c136dba79d3bd43b0ca53e0 100644 --- a/src/UnicaenSynchro/Service/SqlHelper/SqlHelperService.php +++ b/src/UnicaenSynchro/Service/SqlHelper/SqlHelperService.php @@ -8,10 +8,11 @@ use Doctrine\ORM\EntityManager; use DoctrineModule\Persistence\ProvidesObjectManager; use RuntimeException; -class SqlHelperService { +class SqlHelperService +{ use ProvidesObjectManager; - public function executeRequeteRef(EntityManager $entityManager, string $sql, array $params) : array + public function executeRequeteRef(EntityManager $entityManager, string $sql, array $params): array { try { $res = $entityManager->getConnection()->executeQuery($sql, $params); @@ -25,64 +26,105 @@ class SqlHelperService { echo "033[31mUn problème est survenu lors de l'utilisation de la base de donnée\033[0m"; throw new RuntimeException("Un problème est survenu [DBA_Exception]", 0, $e); } + return $tmp; } - public function fetch(EntityManager $entityManager, string $table, array $correspondance, string $type, string $id) : array + + + public function fetch(EntityManager $entityManager, string $table, array $correspondance, string $type, string $id, string $separatorColumn = null, string $separatorValue = null): array { $columns = []; - foreach ($correspondance as $s=>$d) { + foreach ($correspondance as $s => $d) { if ($type === 'source') $columns[] = $s; if ($type === 'destination') $columns[] = $d; } if ($type === 'destination') $columns[] = 'deleted_on'; if ($type === 'destination') $columns[] = 'source_id'; - $sql = "select ".implode(" , ", $columns)." from ".$table; - $data = $this->executeRequeteRef($entityManager, $sql, []); + $sql = "select " . implode(" , ", $columns) . " from " . $table; + if($separatorColumn !== null && $separatorValue !== ''){ + $sql .= " where " . $separatorColumn . " = '" . $separatorValue . "'"; + } + $data = $this->executeRequeteRef($entityManager, $sql, []); $values = []; foreach ($data as $item) { $values[$item[$id]] = $item; } + + return $values; + } + + + + public function fetchValuesSeparator(EntityManager $entityManager, string $table, string $column): array + { + + + $sql = "select " . $column . " from " . $table . " group by " . $column . ' order by '.$column; + $values = $this->executeRequeteRef($entityManager, $sql, []); + return $values; } + + //todo que ce passe t'il pour les booleans - public function echapValue(?string $value) : string + public function echapValue(?string $value): string { if ($value === null or $value === '') return "null"; - return "'". str_replace("'","''",$value) . "'"; + + return "'" . str_replace("'", "''", $value) . "'"; } - public function insert(EntityManager $entityManager, string $table, array $item, array $correspondance, ?string $source = null) : void + + + + public function insert(EntityManager $entityManager, string $table, array $item, array $correspondance, ?string $source = null): void { - $columns = []; foreach ($correspondance as $d) $columns[] = $d; $columns[] = "created_on"; + $columns = []; + foreach ($correspondance as $d) { + $columns[] = $d; + } + $columns[] = "created_on"; if ($source !== null) $columns[] = 'source_id'; - $values = []; foreach ($correspondance as $s => $d) $values[] = $this->echapValue($item[$s]); $values[] = "now()"; - if ($source !== null) $values[] = "'".$source."'"; - $sql = "insert into ".$table." (".implode(',',$columns).") values (".implode(',',$values).")"; + $values = []; + foreach ($correspondance as $s => $d) { + $values[] = $this->echapValue($item[$s]); + } + $values[] = "now()"; + if ($source !== null) $values[] = "'" . $source . "'"; + $sql = "insert into " . $table . " (" . implode(',', $columns) . ") values (" . implode(',', $values) . ")"; $this->executeRequeteRef($entityManager, $sql, []); } - public function update(EntityManager $entityManager, string $table, array $item, array $correspondance, string $id, ?string $source = null) : void + + + public function update(EntityManager $entityManager, string $table, array $item, array $correspondance, string $id, ?string $source = null): void { - $values = []; foreach ($correspondance as $s => $d) $values[] = $d."=".$this->echapValue($item[$s]); - if ($source !== null) $values[] = "source_id='".$source."'"; + $values = []; + foreach ($correspondance as $s => $d) { + $values[] = $d . "=" . $this->echapValue($item[$s]); + } + if ($source !== null) $values[] = "source_id='" . $source . "'"; $values[] = "updated_on=now()"; - $sql = "update ".$table. " set " . implode(" , ", $values). " where id=:id"; + $sql = "update " . $table . " set " . implode(" , ", $values) . " where id=:id"; $this->executeRequeteRef($entityManager, $sql, ["id" => $id]); } - public function restore(EntityManager $entityManager, string $table, string $id) : void + + public function restore(EntityManager $entityManager, string $table, string $id): void { - $sql = "update ".$table." set deleted_on=NULL where id=:id"; + $sql = "update " . $table . " set deleted_on=NULL where id=:id"; $this->executeRequeteRef($entityManager, $sql, ["id" => $id]); } - public function delete(EntityManager $entityManager, string $table, string $id) : void + + + public function delete(EntityManager $entityManager, string $table, string $id): void { - $sql = "update ".$table." set deleted_on=now() where id=:id"; + $sql = "update " . $table . " set deleted_on=now() where id=:id"; $this->executeRequeteRef($entityManager, $sql, ["id" => $id]); } } \ No newline at end of file diff --git a/src/UnicaenSynchro/Service/Synchronisation/SynchronisationService.php b/src/UnicaenSynchro/Service/Synchronisation/SynchronisationService.php index 008eb24efb6548a66d8f9f7561342e4b4d272ccb..b9981b90b81fb3d65331a0add1f59803279d1626 100644 --- a/src/UnicaenSynchro/Service/Synchronisation/SynchronisationService.php +++ b/src/UnicaenSynchro/Service/Synchronisation/SynchronisationService.php @@ -6,26 +6,44 @@ use DateTime; use Exception; use UnicaenSynchro\Service\SqlHelper\SqlHelperServiceAwareTrait; -class SynchronisationService { +class SynchronisationService +{ use SqlHelperServiceAwareTrait; private array $entityManagers = []; + + + public function setEntityManagers(array $entityManagers): void { $this->entityManagers = $entityManagers; } + + private array $configs = []; + + + public function setConfigs(array $configs): void { $this->configs = $configs; } + + + public function getFromConfig(string $name, string $key) { - return $this->configs[$name][$key]; + if(isset($this->configs[$name][$key])) { + return $this->configs[$name][$key]; + } + return null; } - private function checkDifferences(array $itemSource, array $itemDestination, array $correspondance, ?string $source = null) : bool { + + + private function checkDifferences(array $itemSource, array $itemDestination, array $correspondance, ?string $source = null): bool + { foreach ($correspondance as $idSource => $idCorrespondance) { if ($itemSource[$idSource] != $itemDestination[$idCorrespondance]) { // var_dump($itemSource[$idSource]); @@ -43,10 +61,13 @@ class SynchronisationService { // die(); if ($itemDestination['source_id'] !== $source) return true; } + return false; } - public function synchronise(string $name) : string + + + public function synchronise(string $name): string { try { echo "Synchronisation [" . $name . "]\n"; @@ -55,100 +76,140 @@ class SynchronisationService { echo "Debut: " . $debut->format('d/m/y H:i:s:u') . "\n"; flush(); - $correspondance = $this->getFromConfig($name, 'correspondance'); - $orm_source = $this->entityManagers[$this->getFromConfig($name, 'orm_source')]; - $orm_destination = $this->entityManagers[$this->getFromConfig($name, 'orm_destination')]; - $table_source = $this->getFromConfig($name, 'table_source'); + $correspondance = $this->getFromConfig($name, 'correspondance'); + $orm_source = $this->entityManagers[$this->getFromConfig($name, 'orm_source')]; + $orm_destination = $this->entityManagers[$this->getFromConfig($name, 'orm_destination')]; + $table_source = $this->getFromConfig($name, 'table_source'); $table_destination = $this->getFromConfig($name, 'table_destination'); - $id_source = $this->getFromConfig($name, 'id'); - $source = $this->getFromConfig($name, 'source'); - $id_destination = $correspondance[$id_source]; - - $data_source = $this->getSqlHelperService()->fetch($orm_source, $table_source, $correspondance, 'source', $id_source); - echo count($data_source) . " entrées dans les données sources.\n"; - flush(); - $data_destination = $this->getSqlHelperService()->fetch($orm_destination, $table_destination, $correspondance, 'destination', $id_destination); - $data_destination_on = []; - $data_destination_off = []; - foreach ($data_destination as $item) { - if ($item['deleted_on'] !== null) $data_destination_off[] = $item; else $data_destination_on[] = $item; + $id_source = $this->getFromConfig($name, 'id'); + $source = $this->getFromConfig($name, 'source'); + $id_destination = $correspondance[$id_source]; + $separatorSource = $this->getFromConfig($name, 'separator'); + + if ($separatorSource != null && $separatorSource != "") { + $separatorValuesSource = $this->getSqlHelperService()->fetchValuesSeparator($orm_source, $table_source, $separatorSource); + $separatorValuesDestination = $this->getSqlHelperService()->fetchValuesSeparator($orm_destination, $table_destination, $correspondance[$separatorSource]); + + $separatorValues = array_unique(array_merge( + array_map(function (array $a) use ($separatorSource) { + return $a[$separatorSource]; + }, $separatorValuesSource), + array_map(function ($a) use ($correspondance, $separatorSource) { + return $a[$correspondance[$separatorSource]]; + }, $separatorValuesDestination) + )); + sort($separatorValues); + foreach ($separatorValues as $separatorValue) { + echo "Traitement " . $separatorValue . "\n"; + $data_source = $this->getSqlHelperService()->fetch($orm_source, $table_source, $correspondance, 'source', $id_source, $separatorSource, $separatorValue); + $data_destination = $this->getSqlHelperService()->fetch($orm_destination, $table_destination, $correspondance, 'destination', $id_destination, $separatorSource, $separatorValue); + echo count($data_source) . " entrées dans les données sources.\n"; + $this->doSynchronisation($name, $data_source, $data_destination); + } + } else { + $data_source = $this->getSqlHelperService()->fetch($orm_source, $table_source, $correspondance, 'source', $id_source); + $data_destination = $this->getSqlHelperService()->fetch($orm_destination, $table_destination, $correspondance, 'destination', $id_destination); + echo count($data_source) . " entrées dans les données sources.\n"; + $this->doSynchronisation($name, $data_source, $data_destination); } - echo count($data_destination_on) . "(~" . count($data_destination_off) . ")" . " entrées dans les données cibles actives.\n"; - flush(); - $read = new DateTime(); - echo "Lecture: " . $read->format('d/m/y H:i:s:u') . "(" . ($read->diff($debut))->format('%H:%m:%s:%F') . ")\n"; flush(); + } catch (Exception $e) { + do { + echo "\033[31m" . $e->getMessage() . "\033[0m\n"; + $e = $e->getPrevious(); + } while ($e !== null); + die(); + } - //check for removal - $nbRetrait = 0; - // $texte_retrait = ""; - foreach ($data_destination as $id => $item) { - if ($item['deleted_on'] === null and !isset($data_source[$id])) { - $nbRetrait++; - // $texte_retrait .= "Retrait de ".$id." des données destination.\n"; - $this->getSqlHelperService()->delete($orm_destination, $table_destination, $id); - } + return ""; + } + + + + private function doSynchronisation(string $name, array $data_source, array $data_destination): void + { + $correspondance = $this->getFromConfig($name, 'correspondance'); + $orm_destination = $this->entityManagers[$this->getFromConfig($name, 'orm_destination')]; + $table_destination = $this->getFromConfig($name, 'table_destination'); + $source = $this->getFromConfig($name, 'source'); + + + $debut = new DateTime(); + + $data_destination_on = []; + $data_destination_off = []; + foreach ($data_destination as $item) { + if ($item['deleted_on'] !== null) $data_destination_off[] = $item; else $data_destination_on[] = $item; + } + echo count($data_destination_on) . "(~" . count($data_destination_off) . ")" . " entrées dans les données cibles actives.\n"; + flush(); + + $read = new DateTime(); + echo "Lecture: " . $read->format('d/m/y H:i:s:u') . "(" . ($read->diff($debut))->format('%H:%m:%s:%F') . ")\n"; + flush(); + + //check for removal + $nbRetrait = 0; + // $texte_retrait = ""; + foreach ($data_destination as $id => $item) { + if ($item['deleted_on'] === null and !isset($data_source[$id])) { + $nbRetrait++; + // $texte_retrait .= "Retrait de ".$id." des données destination.\n"; + $this->getSqlHelperService()->delete($orm_destination, $table_destination, $id); } + } - echo "#Retrait: " . $nbRetrait . "\n"; - flush(); - // $log .= $texte_retrait; - - //check for adding - $nbAjout = 0; - // $texte_ajout = ""; - foreach ($data_source as $id => $item) { - if (!isset($data_destination[$id])) { - $nbAjout++; - // $texte_ajout .= "Ajout de ".$id." des données sources.\n"; - $this->getSqlHelperService()->insert($orm_destination, $table_destination, $item, $correspondance, $source); - } + echo "#Retrait: " . $nbRetrait . "\n"; + flush(); + // $log .= $texte_retrait; + + //check for adding + $nbAjout = 0; + // $texte_ajout = ""; + foreach ($data_source as $id => $item) { + if (!isset($data_destination[$id])) { + $nbAjout++; + // $texte_ajout .= "Ajout de ".$id." des données sources.\n"; + $this->getSqlHelperService()->insert($orm_destination, $table_destination, $item, $correspondance, $source); } - echo "#Ajout: " . $nbAjout . "\n"; - flush(); - // $log .= $texte_ajout; - - //check for restauration - $nbRestauration = 0; - // $texte_restauration = ""; - foreach ($data_source as $id => $item) { - if (isset($data_destination[$id]) and $data_destination[$id]["deleted_on"] !== null) { - $nbRestauration++; - // $texte_restauration .= "Restauration de ".$id." des données destinations.\n"; - $this->getSqlHelperService()->restore($orm_destination, $table_destination, $id); - } + } + echo "#Ajout: " . $nbAjout . "\n"; + flush(); + // $log .= $texte_ajout; + + //check for restauration + $nbRestauration = 0; + // $texte_restauration = ""; + foreach ($data_source as $id => $item) { + if (isset($data_destination[$id]) and $data_destination[$id]["deleted_on"] !== null) { + $nbRestauration++; + // $texte_restauration .= "Restauration de ".$id." des données destinations.\n"; + $this->getSqlHelperService()->restore($orm_destination, $table_destination, $id); } - echo "#Restauration: " . $nbRestauration . "\n"; - flush(); - // $log .= $texte_restauration; - - //check for modification - $nbModification = 0; - // $texte_modication = ""; - foreach ($data_source as $id => $item) { - if (isset($data_destination[$id]) and $this->checkDifferences($item, $data_destination[$id], $correspondance, $source)) { - $nbModification++; - // $texte_modication .= "Modif de ".$id." des données sources.\n"; - $this->getSqlHelperService()->update($orm_destination, $table_destination, $item, $correspondance, $id, $source); - } + } + echo "#Restauration: " . $nbRestauration . "\n"; + flush(); + // $log .= $texte_restauration; + + //check for modification + $nbModification = 0; + // $texte_modication = ""; + foreach ($data_source as $id => $item) { + if (isset($data_destination[$id]) and $this->checkDifferences($item, $data_destination[$id], $correspondance, $source)) { + $nbModification++; + // $texte_modication .= "Modif de ".$id." des données sources.\n"; + $this->getSqlHelperService()->update($orm_destination, $table_destination, $item, $correspondance, $id, $source); } - echo "#Modification: " . $nbModification . "\n"; - flush(); - // $log .= $texte_modication; - - $fin = new DateTime(); - echo "Fin: " . $fin->format('d/m/y H:i:s:u') . "\n"; + } + echo "#Modification: " . $nbModification . "\n"; + flush(); + // $log .= $texte_modication; - echo "Durée de la synchronisation: " . ($fin->diff($debut))->format('%H:%m:%s:%F') . "\n"; + $fin = new DateTime(); + echo "Fin: " . $fin->format('d/m/y H:i:s:u') . "\n"; - return ""; - } catch (Exception $e) { - do { - echo "\033[31m".$e->getMessage() . "\033[0m\n"; - $e = $e->getPrevious(); - } while ($e !== null); - die(); - } + echo "Durée de la synchronisation: " . ($fin->diff($debut))->format('%H:%m:%s:%F') . "\n"; } + } \ No newline at end of file