about summary refs log tree commit homepage
path: root/lib/PublicInbox/LeiMailSync.pm
diff options
context:
space:
mode:
authorEric Wong <e@80x24.org>2021-09-21 07:41:50 +0000
committerEric Wong <e@80x24.org>2021-09-21 19:18:35 +0000
commit8eaa877179910dce156179e9025d1e0df34089d8 (patch)
tree989189ccfd54d820144ce9593a9694fa18522d67 /lib/PublicInbox/LeiMailSync.pm
parent0c385e6500f26babc47a0768b730ea38e290a5f5 (diff)
downloadpublic-inbox-8eaa877179910dce156179e9025d1e0df34089d8.tar.gz
NNTP servers, IMAP servers, and various MUAs may recycle
"unique" identifiers due to software bugs or careless BOFHs.
Warn about them, but always be prepared to account for them.
Diffstat (limited to 'lib/PublicInbox/LeiMailSync.pm')
-rw-r--r--lib/PublicInbox/LeiMailSync.pm20
1 files changed, 10 insertions, 10 deletions
diff --git a/lib/PublicInbox/LeiMailSync.pm b/lib/PublicInbox/LeiMailSync.pm
index d9b9e117..3e725d30 100644
--- a/lib/PublicInbox/LeiMailSync.pm
+++ b/lib/PublicInbox/LeiMailSync.pm
@@ -66,6 +66,7 @@ CREATE TABLE IF NOT EXISTS blob2num (
         oidbin VARBINARY NOT NULL,
         fid INTEGER NOT NULL, /* folder ID */
         uid INTEGER NOT NULL, /* NNTP article number, IMAP UID, MH number */
+        /* not UNIQUE(fid, uid), since we may have broken servers */
         UNIQUE (oidbin, fid, uid)
 )
 
@@ -78,6 +79,7 @@ CREATE TABLE IF NOT EXISTS blob2name (
         oidbin VARBINARY NOT NULL,
         fid INTEGER NOT NULL, /* folder ID */
         name VARBINARY NOT NULL, /* Maildir basename, JMAP blobId */
+        /* not UNIQUE(fid, name), since we may have broken software */
         UNIQUE (oidbin, fid, name)
 )
 
@@ -522,14 +524,14 @@ EOM
         }
 }
 
-sub imap_oidbin ($$$) {
-        my ($self, $url, $uid) = @_; # $url MUST have UIDVALIDITY
-        my $fid = $self->{fmap}->{$url} //= fid_for($self, $url) // return;
+sub num_oidbin ($$$) {
+        my ($self, $url, $uid) = @_; # $url MUST have UIDVALIDITY if IMAP
+        my $fid = $self->{fmap}->{$url} //= fid_for($self, $url) // return ();
         my $sth = $self->{dbh}->prepare_cached(<<EOM, undef, 1);
-SELECT oidbin FROM blob2num WHERE fid = ? AND uid = ?
+SELECT oidbin FROM blob2num WHERE fid = ? AND uid = ? ORDER BY _rowid_
 EOM
         $sth->execute($fid, $uid);
-        $sth->fetchrow_array;
+        map { $_->[0] } @{$sth->fetchall_arrayref};
 }
 
 sub name_oidbin ($$$) {
@@ -539,10 +541,10 @@ sub name_oidbin ($$$) {
 SELECT oidbin FROM blob2name WHERE fid = ? AND name = ?
 EOM
         $sth->execute($fid, $nm);
-        $sth->fetchrow_array;
+        map { $_->[0] } @{$sth->fetchall_arrayref};
 }
 
-sub imap_oid {
+sub imap_oidhex {
         my ($self, $lei, $uid_uri) = @_;
         my $mailbox_uri = $uid_uri->clone;
         $mailbox_uri->uid(undef);
@@ -550,12 +552,10 @@ sub imap_oid {
         if (my $err = $self->arg2folder($lei, $folders)) {
                 if ($err->{fail}) {
                         $lei->qerr("# no sync information for $mailbox_uri");
-                        return;
                 }
                 $lei->qerr(@{$err->{qerr}}) if $err->{qerr};
         }
-        my $oidbin = imap_oidbin($self, $folders->[0], $uid_uri->uid);
-        $oidbin ? unpack('H*', $oidbin) : undef;
+        map { unpack('H*',$_) } num_oidbin($self, $folders->[0], $uid_uri->uid)
 }
 
 1;