Added the possibility, for each set of records with the same URI, to choose one record to keep and delete the others, or to automatically keep the record with the lowest ID and delete the others
This commit is contained in:
parent
90e85f8182
commit
483fbcd103
1 changed files with 166 additions and 21 deletions
|
@ -1,49 +1,194 @@
|
|||
#!/usr/bin/php
|
||||
<?php
|
||||
|
||||
const N="\n";
|
||||
/*
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
define('N',"\n");
|
||||
define('SNAME',basename(__FILE__));
|
||||
define('CONFIGFP',__DIR__.'/../../conf/mustard.ini');
|
||||
|
||||
$help='SYNOPSYS
|
||||
'.SNAME.' [options]
|
||||
DESCRIPTION
|
||||
This is a script to check the «Instances» table of mastostart database for
|
||||
multiple records with the same URI value.
|
||||
OPTIONS
|
||||
-d, --delete
|
||||
For each URI with multiple records, give the possibility to interactively
|
||||
choose which record to keep, and delete the others (default); or to
|
||||
automatically keep the record with the lowest ID and delete the others
|
||||
(see below).
|
||||
-I, --nonint
|
||||
Disable interactive mode.
|
||||
-h, --help
|
||||
Show this help text and exit.'.N;
|
||||
|
||||
$opts=[
|
||||
'delete'=>false,
|
||||
'interactive'=>true
|
||||
];
|
||||
|
||||
for ($i=1; $i<$argc; $i++) {
|
||||
if ($argv[$i]=='-h' || $argv[$i]=='--help') {
|
||||
mexit($help,0);
|
||||
} elseif ($argv[$i]=='-d' || $argv[$i]=='--delete') {
|
||||
$opts['delete']=true;
|
||||
} elseif ($argv[$i]=='-I' || $argv[$i]=='--nonint') {
|
||||
$opts['interactive']=false;
|
||||
} else {
|
||||
mexit('Don’t know how to interpret «'.$argv[$i].'», please read the help text using «-h» or «--help» option.'.N,1);
|
||||
}
|
||||
}
|
||||
|
||||
use function mysqli_real_escape_string as myesc;
|
||||
|
||||
function mexit($msg,$code) {
|
||||
echo($msg);
|
||||
global $link;
|
||||
if (isset($link)) mysqli_close($link);
|
||||
if ($code>0)
|
||||
fwrite(STDERR,$msg);
|
||||
else
|
||||
echo($msg);
|
||||
exit($code);
|
||||
}
|
||||
|
||||
$iniarr=@parse_ini_file(__DIR__.'/../../conf/mustard.ini')
|
||||
or mexit('Impossibile aprire il file di configurazione.'.N,1);
|
||||
$link=mysqli_connect($iniarr['db_host'],$iniarr['db_admin_name'],$iniarr['db_admin_password'],$iniarr['db_name'],$iniarr['db_port'],$iniarr['db_socket'])
|
||||
or mexit('Impossibile connettersi al database: '.mysqli_connect_error().' ['.mysqli_connect_errno().']'.N,1);
|
||||
$iniarr=@parse_ini_file(CONFIGFP)
|
||||
or mexit('Could not open config file «'.CONFIGFP.'».'.N,1);
|
||||
|
||||
try { $link=mysqli_connect($iniarr['db_host'],$iniarr['db_admin_name'],$iniarr['db_admin_password'],$iniarr['db_name'],$iniarr['db_port'],$iniarr['db_socket']); }
|
||||
catch (Exception $error) { mexit('Could not connect to mysql server: '.$error->getMessage().' (error code: '.$error->getCode().').'.N,1); }
|
||||
mysqli_set_charset($link,'utf8mb4');
|
||||
|
||||
function myq(&$l,$q) {
|
||||
try {
|
||||
$res=mysqli_query($l,$q);
|
||||
}
|
||||
catch (Exception $e) {
|
||||
echo('query «'.$q.'» failed: '.$e->getMessage().' (error code: '.$e->getCode().').'.N);
|
||||
exit(3);
|
||||
}
|
||||
return($res);
|
||||
}
|
||||
|
||||
$insts=[];
|
||||
$res=mysqli_query($link,'SELECT * FROM Instances');
|
||||
while ($row=mysqli_fetch_assoc($res))
|
||||
$insts[$row['URI']][]=$row;
|
||||
|
||||
mysqli_close($link);
|
||||
//ID: 83; FirstSeen: 1602617889; IsMastodon: 0; Dead: 0; New: 0; Good: 0; Chosen: 0; Priority: NULL; Visible: 0; Noxious: 0; NoxReason: NULL; NoxLastModTS: NULL; URI: ambrosia.cafe; Title: ambrosia café; ShortDesc: NULL; LongDesc: Pleroma: An efficient and flexible fediverse server; OurDesc: NULL; OurDescEN: NULL; LocalityID: NULL; OurLangsLock: 0; Email: admin@ambrosia.cafe; Software: NULL; Version: 2.7.2 (compatible; Pleroma 2.4.2); UserCount: 3; StatusCount: 299; DomainCount: 2900; ActiveUsersMonth: NULL; ActiveUsersHalfYear: NULL; Thumb: https://ambrosia.cafe/instance/thumbnail.jpeg; RegOpen: 0; RegReqApproval: 0; MaxTootChars: 5000; AdmAccount: NULL; AdmDisplayName: NULL; AdmCreatedAt: NULL; AdmNote: NULL; AdmURL: NULL; AdmAvatar: NULL; AdmHeader: NULL; LastCheckOk: 0; GuestID: NULL; LastGuestEdit: NULL; InsertTS: NULL; RPos: 4291;
|
||||
|
||||
$i=0;
|
||||
foreach ($insts as $uri=>$rows) {
|
||||
$cr=count($rows);
|
||||
if ($cr>1) {
|
||||
$i++;
|
||||
echo('>>>>>>>>>>>>>>>> '.$uri.': '.$cr.N.N);
|
||||
foreach ($rows as $row) {
|
||||
foreach ($row as $key=>$val) {
|
||||
echo($key.': '.pr($val).'; ');
|
||||
$tot=0;
|
||||
foreach ($insts as $uri=>$rows)
|
||||
if (count($rows)>1) $tot++;
|
||||
|
||||
if ($tot>0 && $opts['delete']) {
|
||||
$i=0;
|
||||
foreach ($insts as $uri=>$rows) {
|
||||
$cr=count($rows);
|
||||
if ($cr>1) {
|
||||
$i++;
|
||||
echo('<<< '.$i.'/'.$tot.': '.$uri.' ('.$cr.' records) >>>'.N.N);
|
||||
$buff=[];
|
||||
foreach ($rows as $row) {
|
||||
$row['FirstSeen']=utstd($row['FirstSeen']);
|
||||
$row['NoxLastModTS']=utstd($row['NoxLastModTS']);
|
||||
$row['AdmCreatedAt']=utstd($row['AdmCreatedAt']);
|
||||
$row['LastGuestEdit']=utstd($row['LastGuestEdit']);
|
||||
$row['InsertTS']=utstd($row['InsertTS']);
|
||||
$out='';
|
||||
foreach ($row as $key=>$val)
|
||||
$out.=$key.': '.pr($val).'; ';
|
||||
$out=substr($out,0,-2);
|
||||
//echo($out.N.N);
|
||||
$buff[$row['ID']]=['id'=>$row['ID'],'row'=>$out];
|
||||
}
|
||||
asort($buff);
|
||||
$ii=0;
|
||||
$recs=[];
|
||||
foreach ($buff as $rec) {
|
||||
$ii++;
|
||||
$recs[$ii]=$rec;
|
||||
echo($ii.': '.$rec['row'].N.N);
|
||||
}
|
||||
if ($opts['interactive']) {
|
||||
$ans=[];
|
||||
for ($iii=1; $iii<=$ii; $iii++)
|
||||
$ans[]=$iii;
|
||||
$ans[]='e';
|
||||
$inp=null;
|
||||
while (!in_array($inp,$ans)) {
|
||||
echo('Which one do you want to keep? ['.implode('/',$ans).'] ');
|
||||
$inp=strtolower(trim(fgets(STDIN)));
|
||||
}
|
||||
} else {
|
||||
$inp=1;
|
||||
}
|
||||
if ($inp=='e') {
|
||||
mexit('Ok, bye :-)'.N,0);
|
||||
} else {
|
||||
$inp+=0;
|
||||
echo(N.'Ok, i’ll keep the record with ID='.$recs[$inp]['id'].N);
|
||||
foreach ($recs as $key=>$rec) {
|
||||
if ($key!=$inp) {
|
||||
echo('Deleting record with ID='.$rec['id'].' ...'.N);
|
||||
myq($link,'DELETE FROM Instances WHERE ID='.$rec['id']);
|
||||
echo('Deleted '.mysqli_affected_rows($link).' records from Instances table.'.N);
|
||||
myq($link,'DELETE FROM InstActivity WHERE InstID='.$rec['id']);
|
||||
echo('Deleted '.mysqli_affected_rows($link).' records from InstActivity table.'.N);
|
||||
myq($link,'DELETE FROM InstChecks WHERE InstID='.$rec['id']);
|
||||
echo('Deleted '.mysqli_affected_rows($link).' records from InstChecks table.'.N);
|
||||
myq($link,'DELETE FROM InstFinancing WHERE InstID='.$rec['id']);
|
||||
echo('Deleted '.mysqli_affected_rows($link).' records from InstFinancing table.'.N);
|
||||
myq($link,'DELETE FROM InstLangs WHERE InstID='.$rec['id']);
|
||||
echo('Deleted '.mysqli_affected_rows($link).' records from InstLangs table.'.N);
|
||||
myq($link,'DELETE FROM InstOurLangs WHERE InstID='.$rec['id']);
|
||||
echo('Deleted '.mysqli_affected_rows($link).' records from InstOurLangs table.'.N);
|
||||
myq($link,'DELETE FROM InstPolicies WHERE InstID='.$rec['id']);
|
||||
echo('Deleted '.mysqli_affected_rows($link).' records from InstPolicies table.'.N);
|
||||
myq($link,'DELETE FROM InstTags WHERE InstID='.$rec['id']);
|
||||
echo('Deleted '.mysqli_affected_rows($link).' records from InstTags table.'.N);
|
||||
myq($link,'DELETE FROM InstTrends WHERE InstID='.$rec['id']);
|
||||
echo('Deleted '.mysqli_affected_rows($link).' records from InstTrends table.'.N);
|
||||
$users=myq($link,'SELECT ID FROM Users WHERE InstID='.$rec['id']);
|
||||
$iii=0;
|
||||
while ($user=mysqli_fetch_assoc($users)) {
|
||||
myq($link,'DELETE FROM UsersFields WHERE UserID='.$user['ID']);
|
||||
$iii+=mysqli_affected_rows($link);
|
||||
}
|
||||
echo('Deleted '.$iii.' records from UsersFields table.'.N);
|
||||
myq($link,'DELETE FROM Users WHERE InstID='.$rec['id']);
|
||||
echo('Deleted '.mysqli_affected_rows($link).' records from Users table.'.N);
|
||||
}
|
||||
}
|
||||
echo(N);
|
||||
}
|
||||
echo(N.N);
|
||||
}
|
||||
}
|
||||
$inp='x';
|
||||
}
|
||||
echo('Total dupes: '.$i.N);
|
||||
echo('Total dupes: '.$tot.N);
|
||||
mysqli_close($link);
|
||||
exit(0);
|
||||
|
||||
function utstd($val) {
|
||||
if (is_null($val)) return(null);
|
||||
$val=round($val);
|
||||
return(date('Y-m-d H:i:s',$val));
|
||||
}
|
||||
function pr($val) {
|
||||
if (is_null($val))
|
||||
return('NULL');
|
||||
if (is_null($val)) return('NULL');
|
||||
return($val);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue