Skip to content
Snippets Groups Projects
Commit 432155ab authored by Laurent Lecluse's avatar Laurent Lecluse
Browse files

Nouvel outil Comparator

parent 81a86e5f
Branches
Tags 1.4.0
No related merge requests found
Pipeline #37207 passed
1.4.0 (16/04/2025)
------------------
- [Nouvel outil Comparator](doc/tools/comparator.md)
1.3.1 (25/03/2025)
------------------
......
# Comparator
Le comparator permet de lister les différences entre deux requêtes et de les afficher en HTML le cas échéant.
Exemple d'usage du comparator :
```php
/**
* @var $container \Psr\Container\ContainerInterface
*/
$bdd = $container->get(\Unicaen\BddAdmin\Bdd::class);
$comparator = new \Unicaen\BddAdmin\Tools\Comparator($bdd);
$sql1 = "SELECT * FROM v_contrat_main_old";
$sql2 = "SELECT * FROM v_contrat_main";
$keyCols = ['CONTRAT_ID']; // liste de colonnes permettant d'établir la correspondance entre les deux requêtes
$ignoreCols = [ // on peut ignorer des colonnes pour lesquelles il y a des différences qu'on estime "normales" ou qui sont à étudier pour + tard
'FORMULE_RESULTAT_ID', // colonne supprimée
'totalDiviseParDix', // colonne supprimée
'tauxId', // colonne supprimée
'tauxMajoreId', // colonne supprimée
'heuresPeriodeEssai', // nouvelle colonne
'heuresPrimePrecarite', // nouvelle colonne
'horodatage', // dates générées à partir de NOW => pas de pb
'date_creation', // formatage pourri ancienne => Ok maintenant
'date_contrat_lie', // formatage pourri ancienne => Ok maintenant
'tauxHoraireDate', // formatage pourri ancienne => Ok maintenant
'tauxMajoreHoraireDate', // colonne vide avant
'heuresFormation', // toutes vides ancienne vue
'enteteAutresHeures', // problèmes trouvés dans ancienne vue v_contrat_main
'legendeAutresHeures', // problèmes trouvés dans ancienne vue v_contrat_main
'pays_nationalite', // colonnes vides dans ancienne, car on ne prenait en compte que les données perso sans tenir compte de la table intervenant
'serviceTotalPaye', // le nouvel calcul met le taux de CP à 0 pour les enseignements, pas l'ancienne vue
/* à contrôler + finement */
'titreCourt', // lié au pb parentalité des avenants ??
'totalHETD', // arrondis à retester ?
//avenant1 contrat1 modifieComplete n titre reste => avenants qui se transforment en contrat et vice versa ??
// contrats concernés : 2479, 40336, 36972, 36028, 19628, 1912, 1854
];
$onlyCols = [ // On peut cibler sur certaines collonnes uniquement afin de ne pas être noyé dans les différences à examiner
//'hetdContrat'
];
// On injecte tout ça dans le comparator
$comparator->setQuery1($sql1);
$comparator->setQuery2($sql2);
$comparator->setKeyColumns($keyCols);
$comparator->setIgnoreColumns($ignoreCols);
$comparator->setOnlyColumns($onlyCols);
// limit est à 1000 par défaut, mais il est redéfini ici à titre d'exemple
$comparator->setLimit(1000);
// On lance l'outil qui nous retourne un array en résultat
$result = $comparator->run();
// on peut transformer cet array en HTML pour affichage
echo $comparator->html($result);
```
Et voici un exemple de résultat :
![Capture d'écran](comparator.png)
\ No newline at end of file
doc/tools/comparator.png

70.8 KiB

<?php
namespace Unicaen\BddAdmin\Tools;
use Unicaen\BddAdmin\Bdd;
use Unicaen\BddAdmin\BddAwareTrait;
class Comparator
{
use BddAwareTrait;
private string $query1;
private string $query2;
private array $keyColumns = [];
private array $onlyColumns = [];
private array $ignoreColumns = [];
private int $limit = 1000;
public function __construct(Bdd $bdd)
{
$this->bdd = $bdd;
}
public function getQuery1(): string
{
return $this->query1;
}
public function setQuery1(string $query1): Comparator
{
$this->query1 = $query1;
return $this;
}
public function getQuery2(): string
{
return $this->query2;
}
public function setQuery2(string $query2): Comparator
{
$this->query2 = $query2;
return $this;
}
public function getKeyColumns(): array
{
return $this->keyColumns;
}
public function setKeyColumns(array $keyColumns): Comparator
{
$this->keyColumns = $keyColumns;
return $this;
}
public function getOnlyColumns(): array
{
return $this->onlyColumns;
}
public function setOnlyColumns(array $onlyColumns): Comparator
{
$this->onlyColumns = $onlyColumns;
return $this;
}
public function getIgnoreColumns(): array
{
return $this->ignoreColumns;
}
public function setIgnoreColumns(array $ignoreColumns): Comparator
{
$this->ignoreColumns = $ignoreColumns;
return $this;
}
public function getLimit(): int
{
return $this->limit;
}
public function setLimit(int $limit): Comparator
{
$this->limit = $limit;
return $this;
}
public function run(): array
{
$diffCols = [];
$cols = [];
$data = [];
$count1 = 0;
$count2 = 0;
$p1 = $this->getBdd()->selectEach($this->getQuery1());
$first = true;
while ($line = $p1->next()) {
$count1++;
if ($first) {
$cols = array_keys($line);
}
$k = $this->key($line);
if (!array_key_exists($k, $data)) {
$data[$k] = ['key' => $this->keyArray($line)];
}
foreach ($line as $col => $value) {
if (in_array($col, $this->keyColumns) || in_array($col, $this->ignoreColumns)) {
unset($line[$col]);
}
if (!empty($this->onlyColumns) && !in_array($col, $this->onlyColumns)) {
unset($line[$col]);
}
if ($value == null) {
unset($line[$col]);
}
}
$data[$k][1] = $line;
$first = false;
}
$p2 = $this->getBdd()->selectEach($this->getQuery2());
$first = true;
while ($line = $p2->next()) {
$count2++;
if ($first) {
foreach ($line as $col => $null) {
if (!in_array($col, $cols)) {
$cols[] = $col;
}
}
}
$k = $this->key($line);
if (!array_key_exists($k, $data)) {
$data[$k] = ['key' => $this->keyArray($line)];
}
foreach ($line as $col => $value) {
if (in_array($col, $this->keyColumns) || in_array($col, $this->ignoreColumns)) {
unset($line[$col]);
}
if (!empty($this->onlyColumns) && !in_array($col, $this->onlyColumns)) {
unset($line[$col]);
}
if ($value == null) {
unset($line[$col]);
}
}
$data[$k][2] = $line;
$first = false;
}
foreach ($data as $k => $vs) {
foreach ($cols as $col) {
$v1 = isset($vs[1][$col]) ? $vs[1][$col] : null;
$v2 = isset($vs[2][$col]) ? $vs[2][$col] : null;
if ($v1 == $v2) {
unset($data[$k][1][$col]);
unset($data[$k][2][$col]);
} else {
if (!in_array($col, $diffCols)) {
$diffCols[] = $col;
}
}
}
if (empty($data[$k][1]) && empty($data[$k][2])) {
unset($data[$k]);
}
}
sort($diffCols);
return [
'diffCols' => $diffCols,
'data' => $data,
'count1' => $count1,
'count2' => $count2,
];
}
private function key(array $data): string
{
$key = '';
foreach ($this->keyColumns as $col) {
if ($key != '') $key .= '-';
if (isset($data[$col])) {
$key .= $data[$col];
}
}
return $key;
}
private function keyArray(array $data): array
{
$key = [];
foreach ($this->keyColumns as $col) {
$key[$col] = isset($data[$col]) ? $data[$col] : null;
}
return $key;
}
public function html(array $result): string
{
if (!array_key_exists('diffCols', $result) || !array_key_exists('data', $result)) {
throw new \Exception('Le tableau de données doit être un retour de Comparator->run');
}
$diffCols = $result['diffCols'];
$data = $result['data'];
$r = '';
if (count($data) > 0) {
$r .= '';
$r .= '<table class="table table-bordered table-xs">';
$r .= '<thead>';
$r .= '<tr>';
foreach ($this->keyColumns as $col) {
$r .= '<th rowspan="2">' . $col . '</th>';
}
foreach ($diffCols as $col) {
$r .= '<th colspan="2" style="border-left-width: 2px">' . $col . '</th>';
}
$r .= '</tr>';
$r .= '<tr>';
foreach ($diffCols as $col) {
$r .= '<th style="text-align: center;border-left-width: 2px">1</th>';
$r .= '<th style="text-align: center">2</th>';
}
$r .= '</tr>';
$r .= '</thead>';
$r .= '<tbody>';
$count = 0;
foreach ($data as $k => $v) {
$count++;
if ($count > $this->limit) {
break;
}
$r .= '<tr>';
foreach ($this->keyColumns as $col) {
$r .= '<th>' . $v['key'][$col] . '</th>';
}
foreach ($diffCols as $col) {
$r .= '<td style="border-left-width: 2px">' . (isset($v[1][$col]) ? $v[1][$col] : '') . '</td>';
$r .= '<td>' . (isset($v[2][$col]) ? $v[2][$col] : '') . '</td>';
}
$r .= '</tr>';
}
$r .= '</tbody>';
$r .= '</table>';
}else{
echo 'Aucune différence notée!!!<br />';
}
if (count($data) > $this->limit){
$r .= $this->limit.' lignes affichées sur '.count($data).' au total présentant des différences<br />';
}
$r .= $result['count1'].' lignes issues de la requête 1<br />';
$r .= $result['count2'].' lignes issues de la requête 2<br />';
return $r;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment