Add a cleanup file to the database integrity report.

Use it for fast database cleanup (removal of all broken entries) when you don't want to try recovering inconsistent records.
Note that you may need multiple report to eliminate all the inconsistencies.
This commit is contained in:
Eric
2020-07-10 17:56:42 +02:00
parent acf0548c4c
commit 6320879fe1
9 changed files with 38 additions and 11 deletions

View File

@@ -57,6 +57,7 @@ class DatabaseAnalyzer
if (!empty($sFixItRequest)) if (!empty($sFixItRequest))
{ {
$aErrorsAndFixes[$sClass][$sErrorDesc]['fixit'] = array($sFixItRequest); $aErrorsAndFixes[$sClass][$sErrorDesc]['fixit'] = array($sFixItRequest);
$aErrorsAndFixes[$sClass][$sErrorDesc]['cleanup'] = array($sFixItRequest);
} }
} }
else else
@@ -376,8 +377,18 @@ SQL;
{ {
$aFixIt = array(); $aFixIt = array();
$aFixIt[] = "-- Remove inconsistant entries:"; $aFixIt[] = "-- Remove inconsistant entries:";
$sIds = implode(', ', array_keys($aErrorsAndFixes[$sClass][$sErrorDesc]['values'])); $iOffset = 0;
$aFixIt[] = "DELETE `$sTable` FROM `$sTable` WHERE `$sTable`.`$sExtKeyField` IN ($sIds)"; $iStep = 100;
do
{
$aIds = array_slice(array_keys($aErrorsAndFixes[$sClass][$sErrorDesc]['values']), $iOffset, $iStep);
$sIds = implode(', ', $aIds);
$sDelete = "DELETE `$sTable` FROM `$sTable` WHERE `$sTable`.`$sExtKeyField` IN ($sIds)";
$aFixIt[] = $sDelete;
$aErrorsAndFixes[$sClass][$sErrorDesc]['cleanup'][] = $sDelete;
$iOffset += $iStep;
}
while (count($aIds) == $iStep);
$aFixIt[] = ""; $aFixIt[] = "";
$aFixIt[] = "-- Or fix inconsistant values: Replace XXX with the appropriate value"; $aFixIt[] = "-- Or fix inconsistant values: Replace XXX with the appropriate value";
foreach (array_keys($aErrorsAndFixes[$sClass][$sErrorDesc]['values']) as $sKey) foreach (array_keys($aErrorsAndFixes[$sClass][$sErrorDesc]['values']) as $sKey)
@@ -483,13 +494,15 @@ SQL;
*/ */
private function CheckUsers(&$aErrorsAndFixes) private function CheckUsers(&$aErrorsAndFixes)
{ {
$sUserTable = MetaModel::DBGetTable('User'); $sClass = 'User';
$sUserTable = MetaModel::DBGetTable($sClass);
$sLinkTable = MetaModel::DBGetTable('URP_UserProfile'); $sLinkTable = MetaModel::DBGetTable('URP_UserProfile');
$sSelect = "SELECT DISTINCT u.id AS id, u.`login` AS value"; $sSelect = "SELECT DISTINCT u.id AS id, u.`login` AS value";
$sFilter = "FROM `$sUserTable` AS u LEFT JOIN `$sLinkTable` AS l ON l.userid = u.id WHERE l.id IS NULL"; $sFilter = "FROM `$sUserTable` AS u LEFT JOIN `$sLinkTable` AS l ON l.userid = u.id WHERE l.id IS NULL";
$sSelWrongRecs = "$sSelect $sFilter"; $sSelWrongRecs = "$sSelect $sFilter";
$sFixit = "-- Remove the corresponding user(s)"; $sFixit = "-- Remove the corresponding user(s)";
$this->ExecQuery($sSelWrongRecs, $sFixit, Dict::S('DBAnalyzer-Integrity-UsersWithoutProfile'), 'User', $aErrorsAndFixes); $sErrorDesc = Dict::S('DBAnalyzer-Integrity-UsersWithoutProfile');
$this->ExecQuery($sSelWrongRecs, $sFixit, $sErrorDesc, $sClass, $aErrorsAndFixes);
} }

View File

@@ -201,8 +201,10 @@ function DisplayInconsistenciesReport($aResults)
{ {
$sDBToolsFolder = str_replace("\\", '/', APPROOT.'log/'); $sDBToolsFolder = str_replace("\\", '/', APPROOT.'log/');
$sReportFile = 'dbtools-report-'.date('Y-m-d-H-i-s'); $sReportFile = 'dbtools-report-'.date('Y-m-d-H-i-s');
$sCleanupFile = 'dbtools-cleanup-'.date('Y-m-d-H-i-s');
$fReport = fopen($sDBToolsFolder.$sReportFile.'.txt', 'w'); $fReport = fopen($sDBToolsFolder.$sReportFile.'.txt', 'w');
$fCleanUp = fopen($sDBToolsFolder.$sCleanupFile.'.txt', 'w');
fwrite($fReport, 'Database Maintenance tools: '.date('Y-m-d H:i:s')."\r\n"); fwrite($fReport, 'Database Maintenance tools: '.date('Y-m-d H:i:s')."\r\n");
foreach($aResults as $sClass => $aErrorList) foreach($aResults as $sClass => $aErrorList)
{ {
@@ -228,6 +230,15 @@ function DisplayInconsistenciesReport($aResults)
fwrite($fReport, "\r\n"); fwrite($fReport, "\r\n");
} }
if (isset($aError['cleanup']))
{
$aQueries = $aError['cleanup'];
foreach($aQueries as $sQuery)
{
fwrite($fCleanUp, "$sQuery;\r\n");
}
}
$sQueryResult = ''; $sQueryResult = '';
$aIdList = array(); $aIdList = array();
foreach($aError['res'] as $aRes) foreach($aError['res'] as $aRes)
@@ -249,12 +260,15 @@ function DisplayInconsistenciesReport($aResults)
} }
} }
fclose($fReport); fclose($fReport);
fclose($fCleanUp);
$oArchive = new ZipArchive(); $oArchive = new ZipArchive();
$oArchive->open($sDBToolsFolder.$sReportFile.'.zip', ZipArchive::CREATE); $oArchive->open($sDBToolsFolder.$sReportFile.'.zip', ZipArchive::CREATE);
$oArchive->addFile($sDBToolsFolder.$sReportFile.'.txt', $sReportFile.'.txt'); $oArchive->addFile($sDBToolsFolder.$sReportFile.'.txt', $sReportFile.'.txt');
$oArchive->addFile($sDBToolsFolder.$sCleanupFile.'.txt', $sCleanupFile.'.txt');
$oArchive->close(); $oArchive->close();
unlink($sDBToolsFolder.$sReportFile.'.txt'); unlink($sDBToolsFolder.$sReportFile.'.txt');
unlink($sDBToolsFolder.$sCleanupFile.'.txt');
$sReportFile = $sDBToolsFolder.$sReportFile.'.zip'; $sReportFile = $sDBToolsFolder.$sReportFile.'.zip';

View File

@@ -22,7 +22,7 @@ Dict::Add('DE DE', 'German', 'Deutsch', array(
// Dictionary entries go here // Dictionary entries go here
'Menu:DBToolsMenu' => 'DB Tools', 'Menu:DBToolsMenu' => 'DB Tools',
'DBTools:Class' => 'Klasse', 'DBTools:Class' => 'Klasse',
'DBTools:Title' => 'Datenbank-Pflege-Tools', 'DBTools:Title' => 'Datenbank-Pflege-Tools~~',
'DBTools:ErrorsFound' => 'Fehler gefunden', 'DBTools:ErrorsFound' => 'Fehler gefunden',
'DBTools:Error' => 'Fehler', 'DBTools:Error' => 'Fehler',
'DBTools:Count' => 'Anzahl', 'DBTools:Count' => 'Anzahl',

View File

@@ -26,7 +26,7 @@ Dict::Add('EN US', 'English', 'English', array(
// Dictionary entries go here // Dictionary entries go here
'Menu:DBToolsMenu' => 'Database integrity', 'Menu:DBToolsMenu' => 'Database integrity',
'DBTools:Class' => 'Class', 'DBTools:Class' => 'Class',
'DBTools:Title' => 'Database Maintenance Tools', 'DBTools:Title' => 'Database integrity check',
'DBTools:ErrorsFound' => 'Errors Found', 'DBTools:ErrorsFound' => 'Errors Found',
'DBTools:Error' => 'Error', 'DBTools:Error' => 'Error',
'DBTools:Count' => 'Count', 'DBTools:Count' => 'Count',

View File

@@ -25,7 +25,7 @@ Dict::Add('ES CR', 'Spanish', 'Español, Castellaño', array(
// Dictionary entries go here // Dictionary entries go here
'Menu:DBToolsMenu' => 'Herramientas de bases de datos', 'Menu:DBToolsMenu' => 'Herramientas de bases de datos',
'DBTools:Class' => 'Clase', 'DBTools:Class' => 'Clase',
'DBTools:Title' => 'Herramientas de mantenimiento de base de datos', 'DBTools:Title' => 'Herramientas de mantenimiento de base de datos~~',
'DBTools:ErrorsFound' => 'Errores encontrados', 'DBTools:ErrorsFound' => 'Errores encontrados',
'DBTools:Error' => 'Error', 'DBTools:Error' => 'Error',
'DBTools:Count' => 'Cantidad', 'DBTools:Count' => 'Cantidad',

View File

@@ -21,7 +21,7 @@ Dict::Add('FR FR', 'French', 'Français', array(
// Dictionary entries go here // Dictionary entries go here
'Menu:DBToolsMenu' => 'Intégrité base de données', 'Menu:DBToolsMenu' => 'Intégrité base de données',
'DBTools:Class' => 'Classe', 'DBTools:Class' => 'Classe',
'DBTools:Title' => 'Outils maintenance base de données', 'DBTools:Title' => 'Contrôle de l\'intégrité de la base de données',
'DBTools:ErrorsFound' => 'Erreurs trouvées', 'DBTools:ErrorsFound' => 'Erreurs trouvées',
'DBTools:Error' => 'Erreur', 'DBTools:Error' => 'Erreur',
'DBTools:Count' => 'Nombre', 'DBTools:Count' => 'Nombre',

View File

@@ -27,7 +27,7 @@ Dict::Add('NL NL', 'Dutch', 'Nederlands', array(
// Dictionary entries go here // Dictionary entries go here
'Menu:DBToolsMenu' => 'Databasetools', 'Menu:DBToolsMenu' => 'Databasetools',
'DBTools:Class' => 'Klasse', 'DBTools:Class' => 'Klasse',
'DBTools:Title' => 'Onderhoudstools voor de database', 'DBTools:Title' => 'Onderhoudstools voor de database~~',
'DBTools:ErrorsFound' => 'Fouten gevonden', 'DBTools:ErrorsFound' => 'Fouten gevonden',
'DBTools:Error' => 'Fout', 'DBTools:Error' => 'Fout',
'DBTools:Count' => 'Aantal', 'DBTools:Count' => 'Aantal',

View File

@@ -12,7 +12,7 @@ Dict::Add('RU RU', 'Russian', 'Русский', array(
// Dictionary entries go here // Dictionary entries go here
'Menu:DBToolsMenu' => 'Инструменты БД', 'Menu:DBToolsMenu' => 'Инструменты БД',
'DBTools:Class' => 'Класс', 'DBTools:Class' => 'Класс',
'DBTools:Title' => 'Инструменты обслуживания базы данных', 'DBTools:Title' => 'Инструменты обслуживания базы данных~~',
'DBTools:ErrorsFound' => 'Найденные ошибки', 'DBTools:ErrorsFound' => 'Найденные ошибки',
'DBTools:Error' => 'Ошибка', 'DBTools:Error' => 'Ошибка',
'DBTools:Count' => 'Количество', 'DBTools:Count' => 'Количество',

View File

@@ -25,7 +25,7 @@ Dict::Add('ZH CN', 'Chinese', '简体中文', array(
// Dictionary entries go here // Dictionary entries go here
'Menu:DBToolsMenu' => 'DB 工具', 'Menu:DBToolsMenu' => 'DB 工具',
'DBTools:Class' => 'Class~~', 'DBTools:Class' => 'Class~~',
'DBTools:Title' => '数据库维护工具', 'DBTools:Title' => '数据库维护工具~~',
'DBTools:ErrorsFound' => '发现错误', 'DBTools:ErrorsFound' => '发现错误',
'DBTools:Error' => '错误', 'DBTools:Error' => '错误',
'DBTools:Count' => '个数', 'DBTools:Count' => '个数',