aboutsummaryrefslogtreecommitdiff
path: root/src/service/Backup.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/service/Backup.php')
-rw-r--r--src/service/Backup.php59
1 files changed, 35 insertions, 24 deletions
diff --git a/src/service/Backup.php b/src/service/Backup.php
index 45593bb..c30ce5b 100644
--- a/src/service/Backup.php
+++ b/src/service/Backup.php
@@ -156,8 +156,7 @@ class Backup
156 } 156 }
157 } 157 }
158 158
159 // pattern "template method" 159 static public function restoreDatabase(EntityManager $entityManager, string $file_name, array $exclusion_list = []): void
160 static public function restoreDatabase(EntityManager $entityManager, string $file_name): void
161 { 160 {
162 // création d'un backup de sécurité non écrasable 161 // création d'un backup de sécurité non écrasable
163 $date = new DateTime; 162 $date = new DateTime;
@@ -168,20 +167,10 @@ class Backup
168 $version = $entityManager->getConnection()->fetchOne('SELECT VERSION()'); 167 $version = $entityManager->getConnection()->fetchOne('SELECT VERSION()');
169 $engine = stripos($version, 'mariadb') !== false ? 'mariadb' : 'mysql'; 168 $engine = stripos($version, 'mariadb') !== false ? 'mariadb' : 'mysql';
170 169
171 // choisir les tables à restaurer 170 $tables = self::getDBListOfTables($entityManager, $exclusion_list); // choisir les tables à effacer et restaurer, exclure "user"
172 $tables = $entityManager->getConnection()->createSchemaManager()->listTableNames();
173 foreach($tables as $key => $elem){
174 if($elem === TABLE_PREFIX . 'user'){
175 unset($tables[$key]);
176 }
177 }
178 // sécurité cas pas normal
179 if(empty($tables)){
180 throw new RuntimeException("Aucune table à supprimer");
181 }
182 171
183 $tmp = tempnam('../var', 'tmp_db_codes_'); // crée un fichier avec un nom aléatoire et des droits 600 (concurrence) 172 $tmp_db_codes = tempnam('../var', 'tmp_db_codes_'); // crée un fichier avec un nom aléatoire et des droits 600 (concurrence)
184 file_put_contents($tmp, 173 file_put_contents($tmp_db_codes,
185 "[client]\n 174 "[client]\n
186 user=" . Config::$user . "\n 175 user=" . Config::$user . "\n
187 password=" . Config::$password . "\n 176 password=" . Config::$password . "\n
@@ -191,31 +180,53 @@ class Backup
191 180
192 $command = new Process([ 181 $command = new Process([
193 $engine, // mariadb ou mysql 182 $engine, // mariadb ou mysql
194 '--defaults-extra-file=' . $tmp, // pour ne pas enregistrer les codes dans l'historique de la console ou dans les processus de l'OS 183 '--defaults-extra-file=' . $tmp_db_codes, // pour ne pas enregistrer les codes dans l'historique de la console ou dans les processus de l'OS
195 Config::$database 184 Config::$database
196 ]); 185 ]);
197 $command->setInput(file_get_contents(Backup::$backup_dir . '/' . $file_name)); // l'entrée < 186 $command->setInput(file_get_contents(Backup::$backup_dir . '/' . $file_name)); // l'entrée <
198 187
199 188 // utiliser une liste de tables à exclure dynamique
200 try{ 189 try{
201 // tout effacer 190 // tout effacer
202 $tables_with_backquotes = array_map(fn($t) => '`' . $t . '`', $tables); 191 $tables_with_backquotes = array_map(fn($t) => '`' . $t . '`', $tables);
203 $sql = "SET FOREIGN_KEY_CHECKS=0; DROP TABLE " . implode(', ', $tables_with_backquotes) . "; SET FOREIGN_KEY_CHECKS=1;"; 192 if(!empty($tables_with_backquotes)){
204 $entityManager->getConnection()->executeStatement($sql); 193 $sql = "SET FOREIGN_KEY_CHECKS=0; DROP TABLE " . implode(', ', $tables_with_backquotes) . "; SET FOREIGN_KEY_CHECKS=1;";
194 $entityManager->getConnection()->executeStatement($sql);
195 }
205 196
206 // la table user restante va poser problème 197 // copie des tables à ne pas restaurer
207 $entityManager->getConnection()->executeStatement('RENAME TABLE `' . TABLE_PREFIX . 'user` TO `' . TABLE_PREFIX . 'user_dont_touch`;'); 198 foreach($exclusion_list as $excluded){
199 $entityManager->getConnection()->executeStatement('RENAME TABLE `' . TABLE_PREFIX . $excluded . '` TO `' . TABLE_PREFIX . $excluded . '_dont_touch`;');
200 }
208 201
209 // restaurer 202 // restaurer
210 $command->mustRun(); // comme run() mais lance une ProcessFailedException 203 $command->mustRun(); // comme run() mais lance une ProcessFailedException
211 204
212 // remettre table user comme avant 205 // remettre table user comme avant
213 $entityManager->getConnection()->executeStatement('DROP TABLE `' . TABLE_PREFIX . 'user`;'); 206 foreach($exclusion_list as $excluded){
214 $entityManager->getConnection()->executeStatement('RENAME TABLE `' . TABLE_PREFIX . 'user_dont_touch` TO `' . TABLE_PREFIX . 'user`;'); 207 $entityManager->getConnection()->executeStatement('DROP TABLE `' . TABLE_PREFIX . $excluded . '`;');
208 $entityManager->getConnection()->executeStatement('RENAME TABLE `' . TABLE_PREFIX . $excluded . '_dont_touch` TO `' . TABLE_PREFIX . $excluded . '`;');
209 }
215 } 210 }
216 finally{ 211 finally{
217 // exécuté même quand situé après "return" 212 // exécuté même quand situé après "return"
218 unlink($tmp); 213 unlink($tmp_db_codes);
219 } 214 }
220 } 215 }
216
217 static private function getDBListOfTables(EntityManager $entityManager, array $exclusion_list = []): array
218 {
219 $tables = $entityManager->getConnection()->createSchemaManager()->listTableNames();
220 foreach($tables as $key => $elem){
221 foreach($exclusion_list as $excluded){
222 if(!is_string($excluded)){ // cas pas du tout censé arriver!
223 throw new LogicException("Un nom de table doit etre une chaîne de caractères.");
224 }
225 if($elem === TABLE_PREFIX . $excluded){
226 unset($tables[$key]);
227 }
228 }
229 }
230 return $tables;
231 }
221} \ No newline at end of file 232} \ No newline at end of file