]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/LeiMailSync.pm
lei export-kw: new command to export keywords to Maildirs
[public-inbox.git] / lib / PublicInbox / LeiMailSync.pm
index d8242de381c0441dc510b5e1a30e00a0bf9a2c14..32e17c6576da3c269b4dfbf0c268c65d669401c3 100644 (file)
@@ -11,13 +11,7 @@ use PublicInbox::ContentHash qw(git_sha);
 sub dbh_new {
        my ($self, $rw) = @_;
        my $f = $self->{filename};
-       my $creat;
-       if (!-f $f && $rw) {
-               require PublicInbox::Spawn;
-               open my $fh, '+>>', $f or die "failed to open $f: $!";
-               PublicInbox::Spawn::nodatacow_fd(fileno($fh));
-               $creat = 1;
-       }
+       my $creat = $rw && !-s $f;
        my $dbh = DBI->connect("dbi:SQLite:dbname=$f",'','', {
                AutoCommit => 1,
                RaiseError => 1,
@@ -144,6 +138,16 @@ DELETE FROM blob2num WHERE fid = ? AND uid = ?
        $sth->execute($fid, $id);
 }
 
+# Maildir-only
+sub mv_src {
+       my ($self, $folder, $oidbin, $id, $newbn) = @_;
+       my $fid = $self->{fmap}->{$folder} //= _fid_for($self, $folder, 1);
+       my $sth = $self->{dbh}->prepare_cached(<<'');
+UPDATE blob2name SET name = ? WHERE fid = ? AND oidbin = ? AND name = ?
+
+       $sth->execute($newbn, $fid, $oidbin, $$id);
+}
+
 # read-only, iterates every oidbin + UID or name for a given folder
 sub each_src {
        my ($self, $folder, $cb, @args) = @_;
@@ -239,9 +243,16 @@ WHERE b.oidbin = ?
        $b2n->execute(pack('H*', $oidhex));
        while (my ($d, $n) = $b2n->fetchrow_array) {
                substr($d, 0, length('maildir:')) = '';
-               my $f = "$d/" . ($n =~ /:2,[a-zA-Z]*\z/ ? "cur/$n" : "new/$n");
-               open my $fh, '<', $f or next;
-               if (-s $fh) {
+               # n.b. both mbsync and offlineimap use ":2," as a suffix
+               # in "new/", despite (from what I understand of reading
+               # <https://cr.yp.to/proto/maildir.html>), the ":2," only
+               # applies to files in "cur/".
+               my @try = $n =~ /:2,[a-zA-Z]+\z/ ? qw(cur new) : qw(new cur);
+               for my $x (@try) {
+                       my $f = "$d/$x/$n";
+                       open my $fh, '<', $f or next;
+                       # some (buggy) Maildir writers are non-atomic:
+                       next unless -s $fh;
                        local $/;
                        my $raw = <$fh>;
                        if ($vrfy && git_sha(1, \$raw)->hexdigest ne $oidhex) {