From d7dadcee2550d438066501e576ab16f1134b49f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Laurent=20L=C3=A9cluse?= <laurent.lecluse@unicaen.fr>
Date: Fri, 19 Jan 2024 10:57:30 +0100
Subject: [PATCH] =?UTF-8?q?Gestion=20r=C3=A9par=C3=A9e=20des=20nouvelles?=
 =?UTF-8?q?=20colonnes=20NOT=20NULL=20sans=20valeurs=20par=20d=C3=A9faut?=
 =?UTF-8?q?=20sur=20des=20tables=20existantes=20avec=20des=20donn=C3=A9es?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/Driver/Oracle/TableManager.php     | 25 +++++++++++++++++++------
 src/Driver/Postgresql/TableManager.php | 25 +++++++++++++++++++------
 2 files changed, 38 insertions(+), 12 deletions(-)

diff --git a/src/Driver/Oracle/TableManager.php b/src/Driver/Oracle/TableManager.php
index e25d656..6e91b34 100644
--- a/src/Driver/Oracle/TableManager.php
+++ b/src/Driver/Oracle/TableManager.php
@@ -486,9 +486,18 @@ END;';
 
     private function isEmpty(string $table): bool
     {
-        $r = $this->bdd->select('SELECT * FROM ' . $table, [], ['fetch' => $this->bdd::FETCH_ONE]);
+        $r = $this->bdd->selectOne('SELECT * FROM ' . $table);
 
-        return false === $r;
+        return null === $r;
+    }
+
+
+
+    private function hasEmptyValue(string $table, string $column): bool
+    {
+        $r = $this->bdd->selectOne('SELECT '.$column.' FROM ' . $table.' WHERE '.$column.' IS NULL');
+
+        return null !== $r;
     }
 
 
@@ -503,8 +512,8 @@ END;';
         }
 
         if (!$column['nullable'] && !$noNotNull) {
-            if ($column['default'] === null && $this->isEmpty($table)) {
-                $this->bdd->logError("La colonne $table." . $column['name'] . " n\'a pas pu être déclarée NOT NULL, car des données sont déjà présentes dans la table et aucune valeur par défaut n'a été configurée");
+            if ($column['default'] === null && !$this->isEmpty($table)) {
+                $this->bdd->logMsg("La colonne $table." . $column['name'] . " ne sera pas déclarée NOT NULL, car des données sont déjà présentes dans la table et aucune valeur par défaut n'a été configurée");
             } else {
                 $cp[] = "NOT NULL ENABLE";
             }
@@ -551,8 +560,12 @@ END;';
         if ($this->isColDiffNullable($old, $new)) {
             if ($this->sendEvent()->getReturn('no-exec')) return;
 
-            $sql = "ALTER TABLE \"$table\" MODIFY (\"$column\" " . ($new['nullable'] ? '' : 'NOT ') . "NULL)";
-            $this->addQuery($sql, 'Changement d\'état de la colonne ' . $column . ' de la table ' . $table);
+            if ($this->hasEmptyValue($table, $column)){
+                $this->bdd->logMsg('La colonne '.$table.'.'.$column.' n\'a pas pu être déclarée NOT NULL');
+            }else{
+                $sql = "ALTER TABLE \"$table\" MODIFY (\"$column\" " . ($new['nullable'] ? '' : 'NOT ') . "NULL)";
+                $this->addQuery($sql, 'Changement d\'état de la colonne ' . $column . ' de la table ' . $table);
+            }
         }
     }
 
diff --git a/src/Driver/Postgresql/TableManager.php b/src/Driver/Postgresql/TableManager.php
index cb46eda..9dd94bd 100644
--- a/src/Driver/Postgresql/TableManager.php
+++ b/src/Driver/Postgresql/TableManager.php
@@ -601,9 +601,18 @@ class TableManager extends AbstractManager implements TableManagerInterface
 
     private function isEmpty(string $table): bool
     {
-        $r = $this->bdd->select('SELECT * FROM ' . $table, [], ['fetch' => $this->bdd::FETCH_ONE]);
+        $r = $this->bdd->selectOne('SELECT * FROM ' . $table);
 
-        return false === $r;
+        return null === $r;
+    }
+
+
+
+    private function hasEmptyValue(string $table, string $column): bool
+    {
+        $r = $this->bdd->selectOne('SELECT '.$column.' FROM ' . $table.' WHERE '.$column.' IS NULL');
+
+        return null !== $r;
     }
 
 
@@ -618,8 +627,8 @@ class TableManager extends AbstractManager implements TableManagerInterface
         }
 
         if (!$column['nullable'] && !$noNotNull) {
-            if ($column['default'] === null && $this->isEmpty($table)) {
-                $this->bdd->logError("La colonne $table." . $column['name'] . " n\'a pas pu être déclarée NOT NULL, car des données sont déjà présentes dans la table et aucune valeur par défaut n'a été configurée");
+            if ($column['default'] === null && !$this->isEmpty($table)) {
+                $this->bdd->logMsg("La colonne $table." . $column['name'] . " ne sera pas déclarée NOT NULL, car des données sont déjà présentes dans la table et aucune valeur par défaut n'a été configurée");
             } else {
                 $cp[] = "NOT NULL ENABLE";
             }
@@ -666,8 +675,12 @@ class TableManager extends AbstractManager implements TableManagerInterface
         if ($this->isColDiffNullable($old, $new)) {
             if ($this->sendEvent()->getReturn('no-exec')) return;
 
-            $sql = "ALTER TABLE $table ALTER COLUMN $column " . ($new['nullable'] ? 'DROP' : 'SET') . " NOT NULL";
-            $this->addQuery($sql, 'Changement d\'état de la colonne ' . $column . ' de la table ' . $table);
+            if ($this->hasEmptyValue($table, $column)){
+                $this->bdd->logMsg('La colonne '.$table.'.'.$column.' n\'a pas pu être déclarée NOT NULL');
+            }else{
+                $sql = "ALTER TABLE $table ALTER COLUMN $column " . ($new['nullable'] ? 'DROP' : 'SET') . " NOT NULL";
+                $this->addQuery($sql, 'Changement d\'état de la colonne ' . $column . ' de la table ' . $table);
+            }
         }
     }
 
-- 
GitLab