* [PATCH] lei_mail_sync: cleanup stale/dangling fids if possible
@ 2023-04-12 6:19 7% Eric Wong
0 siblings, 0 replies; 1+ results
From: Eric Wong @ 2023-04-12 6:19 UTC (permalink / raw)
To: meta
I'm not sure how it happens or if/when it was fixed, but my
earliest lei installations have hit some
"E: fid=$fid for $oidhex unknown" messages on `lei import'
invocations.
This really should've enabled the foreign keys pragma to begin
with; but we'll probably start using that in the future. For
now, at least rely on a transaction to keep things consistent
in SQLite.
---
lib/PublicInbox/LeiMailSync.pm | 37 +++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 10 deletions(-)
diff --git a/lib/PublicInbox/LeiMailSync.pm b/lib/PublicInbox/LeiMailSync.pm
index 929f525b..69b3d30c 100644
--- a/lib/PublicInbox/LeiMailSync.pm
+++ b/lib/PublicInbox/LeiMailSync.pm
@@ -340,6 +340,17 @@ SELECT $op(uid) FROM blob2num WHERE fid = ?
$ret;
}
+# must be called with lock
+sub _forget_fids ($;@) {
+ my $dbh = shift;
+ $dbh->begin_work;
+ for my $t (qw(blob2name blob2num folders)) {
+ my $sth = $dbh->prepare_cached("DELETE FROM $t WHERE fid = ?");
+ $sth->execute($_) for @_;
+ }
+ $dbh->commit;
+}
+
# returns a { location => [ list-of-ids-or-names ] } mapping
sub locations_for {
my ($self, $oidbin) = @_;
@@ -380,18 +391,28 @@ sub locations_for {
$sth = $dbh->prepare('SELECT loc FROM folders WHERE fid = ? LIMIT 1');
my $ret = {};
+ my $drop_fids = $dbh->{ReadOnly} ? undef : {};
while (my ($fid, $ids) = each %fid2id) {
$sth->execute($fid);
my ($loc) = $sth->fetchrow_array;
unless (defined $loc) {
+ my $del = '';
+ if ($drop_fids) {
+ $del = ' (deleting)';
+ $drop_fids->{$fid} = $fid;
+ }
my $oidhex = unpack('H*', $oidbin);
- warn "E: fid=$fid for $oidhex unknown:\n", map {
- 'E: '.(ref() ? $$_ : "#$_")."\n";
+ warn "E: fid=$fid for $oidhex stale/unknown:\n", map {
+ 'E: '.(ref() ? $$_ : "#$_")."$del\n";
} @$ids;
next;
}
$ret->{$loc} = $ids;
}
+ if ($drop_fids && scalar(values %$drop_fids)) {
+ my $lk = $self->lock_for_scope;
+ _forget_fids($self->{dbh}, values %$drop_fids);
+ }
scalar(keys %$ret) ? $ret : undef;
}
@@ -598,14 +619,10 @@ EOF
sub forget_folders {
my ($self, @folders) = @_;
my $lk = $self->lock_for_scope;
- for my $folder (@folders) {
- my $fid = delete($self->{fmap}->{$folder}) //
- fid_for($self, $folder) // next;
- for my $t (qw(blob2name blob2num folders)) {
- $self->{dbh}->do("DELETE FROM $t WHERE fid = ?",
- undef, $fid);
- }
- }
+ _forget_fids($self->{dbh}, map {
+ delete($self->{fmap}->{$_}) //
+ fid_for($self, $_) // ();
+ } @folders);
}
# only used for changing canonicalization errors
^ permalink raw reply related [relevance 7%]
Results 1-1 of 1 | reverse | options above
-- pct% links below jump to the message on this page, permalinks otherwise --
2023-04-12 6:19 7% [PATCH] lei_mail_sync: cleanup stale/dangling fids if possible Eric Wong
Code repositories for project(s) associated with this public inbox
https://80x24.org/public-inbox.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).