Skip to content

Commit d7c5b9d

Browse files
J9remmrflos
authored andcommitted
fix(SQL): check if auto_increment and primary are rigth otherwis fix it
1 parent 86edc55 commit d7c5b9d

File tree

3 files changed

+156
-2
lines changed

3 files changed

+156
-2
lines changed

docs/users/fr/usage-avance.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,5 +79,13 @@ Par défaut la page "Modifier les paramètres utilisateurs" permet uniquement de
7979
Lorsqu'un utilisateur tente d'accéder à une page qui nécessite d'être connecté, c'est le formulaire de connexion par défaut qui s'affiche.
8080
**créez une page nommée PageLogin** permet de personnaliser cette page avec un message plus pédagogique et de bénéficier des options de connexions listées ci-dessus en utilisant le composant "Connexion"
8181

82+
## Résoudre le souci de création de listes qui ne s'affichent pas
8283

84+
### Description du problème
8385

86+
- après la création d'une liste, celle-ci ne s'affiche pas correctement dans la liste des listes (accessible avec [ce lien](?BazaR&vue=listes 'Liste des listes :ignore'))
87+
88+
### Correction
89+
90+
1. faire un `/update` sur votre wiki (accessible avec [ce lien](?GererMisesAJour/update 'Forcer la finalisation de la mise à jour :ignore'))
91+
2. vérifier si le problème est résolu. Sinon, suivre les [instructions réservées aux webmasters](./webmaster?id=r%c3%a9parer-la-structure-de-vos-bases-de-donn%c3%a9es)

docs/users/fr/webmaster.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,21 @@ Il va falloir adapter quelques points et sauver ensuite
316316
'mysql_password' => 'motdepassedevotredb',
317317
'base_url' =>'mettreicivotrenomdedomaine/?',
318318
```
319-
320-
319+
320+
## Réparer la structure de vos bases de données
321+
322+
_Lorsque la structure de vos bases de données n'est pas correcte, des soucis peuvent survenir en particuliers lors de la création ou la modification des listes._
323+
324+
1. tenter de forcer la finalisation d'une mise à jour avec le handler `/update` (accessible avec [ce lien](?GererMisesAJour/update 'Forcer la finalisation de la mise à jour :ignore'))
325+
2. si ça ne fonctionne pas:
326+
1. se rendre dans l'interface de gestion de base de données du serveur concerné (`phpmyadmin`)
327+
2. ouvrir en même temps le fichier `setup/sql/create-tables.sql` depuis votre wiki ([fichier à télécharger](setup/sql/create-tables.sql ':ignore'))
328+
3. vérifier dans la structure de chaque table de votre serveur (`phpmyadmin`) que chaque colonne est correctement définie.
329+
4. puis, dans cette ordre, modifier la colonne qui doit être en `AUTOINCREMENT` pour avoir `A.I.` cochée. Normalement, ceci corrige les soucis d'index pour la table concernée et définie la colonne comme primaire.
330+
5. puis, pour les index (`KEY` dans le fichier `create-tables.sql`), définir manuellement chaque index pour la table concernée
331+
6. vérifier que l'affichage et la modification des fiches fonctionnes à nouveau
332+
333+
**Important** : il est vivement conseillé de faire une sauvegarde de votre base de données avant de faire les manipulations.
321334

322335

323336

handlers/UpdateHandler.php

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ public function run()
111111
}
112112
$output .= $this->fixDefaultCommentsAcls();
113113

114+
// check if SQL tables are well defined
115+
$output .= $this->checkSQLTablesThenFixThem($dbService);
116+
114117
// update user table to increase size of password
115118
if ($this->wiki->services->has(PasswordHasherFactory::class)) {
116119
$passwordHasherFactory = $this->getService(PasswordHasherFactory::class);
@@ -380,4 +383,134 @@ private function calcFieldToString(): string
380383

381384
return $output;
382385
}
386+
387+
/**
388+
* @param DbService $dbService
389+
* @return string $output
390+
*/
391+
private function checkSQLTablesThenFixThem($dbService): string
392+
{
393+
$output = "ℹ️ Checking SQL table structure... ";
394+
try {
395+
foreach ([
396+
['pages','id','int(10) unsigned NOT NULL AUTO_INCREMENT'],
397+
['links','id','int(10) unsigned NOT NULL AUTO_INCREMENT'],
398+
['nature','bn_id_nature','int(10) UNSIGNED NOT NULL AUTO_INCREMENT'],
399+
['referrers','id','int(10) unsigned NOT NULL AUTO_INCREMENT'],
400+
['triples','id','int(10) unsigned NOT NULL AUTO_INCREMENT'],
401+
] as $data) {
402+
$output .= $this->checkThenUpdateColumnAutoincrement($dbService, $data[0], $data[1], $data[2]);
403+
}
404+
foreach ([
405+
['pages','id',['id']],
406+
['links','id',['id']],
407+
['nature','bn_id_nature',['bn_id_nature']],
408+
['referrers','id',['id']],
409+
['triples','id',['id']],
410+
['users','name',['name']],
411+
['acls','page_tag',['page_tag','privilege']],
412+
['acls','privilege',['page_tag','privilege']],
413+
] as $data) {
414+
$output .= $this->checkThenUpdateColumnPrimary($dbService, $data[0], $data[1], $data[2]);
415+
}
416+
$output .= "✅ All is right !<br/>";
417+
} catch (\Throwable $th) {
418+
if ($th->getCode() ===1) {
419+
$output .= "{$th->getMessage()} <br/>";
420+
} else {
421+
$output .= "❌ Not checkcked because of error during tests : {$th->getMessage()}! <br/>";
422+
}
423+
}
424+
425+
return $output;
426+
}
427+
428+
/**
429+
* check if a column has auto_increment then try to update it
430+
* @param $dbService
431+
* @param string $tableName
432+
* @param string $columnName
433+
* @param string $SQL_columnDef
434+
* @return string $output
435+
* @throws \Exception
436+
*/
437+
private function checkThenUpdateColumnAutoincrement($dbService, string $tableName, string $columnName, string $SQL_columnDef): string
438+
{
439+
$output = "";
440+
$data = $this->getColumnInfo($dbService, $tableName, $columnName);
441+
if (empty($data['Extra']) || (is_string($data['Extra']) && strstr($data['Extra'], 'auto_increment') === false)) {
442+
$output .= "<br/> Updating `$columnName` in `$tableName`... ";
443+
$dbService->query("ALTER TABLE {$dbService->prefixTable($tableName)} MODIFY COLUMN `$columnName` $SQL_columnDef;");
444+
$data = $this->getColumnInfo($dbService, $tableName, $columnName);
445+
if (empty($data['Extra']) || (is_string($data['Extra']) && strstr($data['Extra'], 'auto_increment') === false)) {
446+
throw new \Exception("❌ tables `$tableName`, column `$columnName` not updated !", 1);
447+
}
448+
}
449+
return $output;
450+
}
451+
452+
/**
453+
* check if a column is primary then try to update it
454+
* @param $dbService
455+
* @param string $tableName
456+
* @param string $columnName
457+
* @param array $newKeys
458+
* @return string $output
459+
* @throws \Exception
460+
*/
461+
private function checkThenUpdateColumnPrimary($dbService, string $tableName, string $columnName, array $newKeys): string
462+
{
463+
$output = "";
464+
$data = $this->getColumnInfo($dbService, $tableName, $columnName);
465+
if (empty($data['Key']) || $data['Key'] !== "PRI") {
466+
$output .= "<br/> Updating key for `$columnName` in `$tableName`... ";
467+
$newKeysFormatted = implode(
468+
',',
469+
array_map(
470+
function ($key) use ($dbService) {
471+
return "`{$dbService->escape($key)}`";
472+
},
473+
array_filter($newKeys)
474+
)
475+
);
476+
if (!empty($newKeysFormatted)) {
477+
$data = $this->getColumnInfo($dbService, $tableName, 'index');
478+
if (!empty($data)) {
479+
$dbService->query("ALTER TABLE {$dbService->prefixTable($tableName)} DROP PRIMARY KEY;");
480+
}
481+
$dbService->query("ALTER TABLE {$dbService->prefixTable($tableName)} ADD PRIMARY KEY($newKeysFormatted);");
482+
}
483+
$data = $this->getColumnInfo($dbService, $tableName, $columnName);
484+
if (empty($data['Key']) || $data['Key'] !== "PRI") {
485+
throw new \Exception("❌ tables `$tableName`, column `$columnName` key not updated !", 1);
486+
}
487+
}
488+
return $output;
489+
}
490+
491+
/**
492+
* get columnInfo from a table
493+
* @param DbService $dbService
494+
* @param string $tableName
495+
* @param string $columnName
496+
* @return array $data
497+
* @throws \Exception
498+
*/
499+
private function getColumnInfo($dbService, string $tableName, string $columnName): array
500+
{
501+
if ($columnName == 'index') {
502+
$result = $dbService->query("SHOW INDEX FROM {$dbService->prefixTable($tableName)};");
503+
if (@mysqli_num_rows($result) === 0) {
504+
return [];
505+
}
506+
} else {
507+
$result = $dbService->query("SHOW COLUMNS FROM {$dbService->prefixTable($tableName)} LIKE '$columnName';");
508+
if (@mysqli_num_rows($result) === 0) {
509+
throw new \Exception("❌ tables `$tableName` not verified because error while getting `$columnName` column !", 1);
510+
}
511+
}
512+
$data = mysqli_fetch_assoc($result);
513+
mysqli_free_result($result);
514+
return $data;
515+
}
383516
}

0 commit comments

Comments
 (0)