]> Sergey Matveev's repositories - public-inbox.git/blobdiff - lib/PublicInbox/Search.pm
search: support downloading mboxes results with full thread
[public-inbox.git] / lib / PublicInbox / Search.pm
index e6200bfb771d5aa8ff8814c4551de63d74138d80..bc820b648a46205d36f9fc8567e4e687483169de 100644 (file)
@@ -18,9 +18,9 @@ use constant {
        # added for public-inbox 1.6.0+
        BYTES => 3, # IMAP RFC822.SIZE
        UID => 4, # IMAP UID == NNTP article number == Xapian docid
+       THREADID => 5, # RFC 8474, RFC 8621
 
        # TODO
-       # THREADID => ?
        # REPLYCNT => ?, # IMAP ANSWERED
 
        # SCHEMA_VERSION history
@@ -47,7 +47,7 @@ use constant {
        #      public-inbox v1.5.0 adds (still SCHEMA_VERSION=15):
        #      * "lid:" and "l:" for List-Id searches
        #
-       #      v1.6.0 adds BYTES and UID values
+       #      v1.6.0 adds BYTES, UID and THREADID values
        SCHEMA_VERSION => 15,
 };
 
@@ -219,6 +219,12 @@ sub mdocid {
        int(($docid - 1) / $nshard) + 1;
 }
 
+sub mset_to_artnums {
+       my ($self, $mset) = @_;
+       my $nshard = $self->{nshard} // 1;
+       [ map { mdocid($nshard, $_) } $mset->items ];
+}
+
 sub xdb ($) {
        my ($self) = @_;
        $self->{xdb} ||= do {
@@ -320,14 +326,21 @@ sub _enquire_once { # retry_reopen callback
        } else {
                $enquire->set_sort_by_value_then_relevance(TS, $desc);
        }
+
+       # `mairix -t / --threads' or JMAP collapseThreads
+       $enquire->set_collapse_key(THREADID) if $opts->{thread};
+
        my $offset = $opts->{offset} || 0;
        my $limit = $opts->{limit} || 50;
        my $mset = $enquire->get_mset($offset, $limit);
        return $mset if $opts->{mset};
-       my @msgs = map { PublicInbox::Smsg::from_mitem($_) } $mset->items;
-       return \@msgs unless wantarray;
-
-       ($mset->get_matches_estimated, \@msgs)
+       my $nshard = $self->{nshard} // 1;
+       my $i = 0;
+       my %order = map { mdocid($nshard, $_) => ++$i } $mset->items;
+       my @msgs = sort {
+               $order{$a->{num}} <=> $order{$b->{num}}
+       } @{$self->{over_ro}->get_all(keys %order)};
+       wantarray ? ($mset->get_matches_estimated, \@msgs) : \@msgs;
 }
 
 # read-write