-# Copyright (C) 2021 all contributors <meta@public-inbox.org>
+# Copyright (C) all contributors <meta@public-inbox.org>
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
# for maintaining synchronization between lei/store <=> Maildir|MH|IMAP|JMAP
my $f = $self->{filename};
my $creat = $rw && !-s $f;
if ($creat) {
- require PublicInbox::Spawn;
+ require PublicInbox::Syscall;
open my $fh, '+>>', $f or Carp::croak "open($f): $!";
- PublicInbox::Spawn::nodatacow_fd(fileno($fh));
+ PublicInbox::Syscall::nodatacow_fh($fh);
}
my $dbh = DBI->connect("dbi:SQLite:dbname=$f",'','', {
AutoCommit => 1,
my ($self, $folder, $oidbin, $id, $newbn) = @_;
my $lk = $self->lock_for_scope;
my $fid = $self->{fmap}->{$folder} //= fid_for($self, $folder, 1);
+ $self->{dbh}->begin_work;
my $sth = $self->{dbh}->prepare_cached(<<'');
UPDATE blob2name SET name = ? WHERE fid = ? AND oidbin = ? AND name = ?
- my $nr = $sth->execute($newbn, $fid, $oidbin, $$id);
- if ($nr == 0) { # may race with a clear_src, ensure new value exists
+ # eval since unique constraint may fail due to race
+ my $nr = eval { $sth->execute($newbn, $fid, $oidbin, $$id) };
+ if (!defined($nr) || $nr == 0) { # $nr may be `0E0'
+ # may race with a clear_src, ensure new value exists
$sth = $self->{dbh}->prepare_cached(<<'');
INSERT OR IGNORE INTO blob2name (oidbin, fid, name) VALUES (?, ?, ?)
$sth->execute($oidbin, $fid, $newbn);
}
+ $self->{dbh}->commit;
}
# read-only, iterates every oidbin + UID or name for a given folder
next unless -s $fh;
local $/;
my $raw = <$fh>;
- if ($vrfy && git_sha(1, \$raw)->hexdigest ne $oidhex) {
- warn "$f changed $oidhex\n";
- next;
+ if ($vrfy) {
+ my $got = git_sha(1, \$raw)->hexdigest;
+ if ($got ne $oidhex) {
+ warn "$f changed $oidhex => $got\n";
+ next;
+ }
}
return \$raw;
}