Since Message-IDs are no longer unique within Xapian
(but are within the SQLite Msgmap); favor NNTP article
numbers for internal lookups. This will prevent us
from finding the "wrong" internal Message-ID.
defined $mid or return $err;
}
found:
defined $mid or return $err;
}
found:
- my $bytes;
- my $s = eval { $ng->msg_by_mid($mid, \$bytes) } or return $err;
- $s = Email::Simple->new($s);
- my $lines;
+ my $smsg = $ng->search->lookup_article($n) or return $err;
+ my $msg = $ng->msg_by_smsg($smsg) or return $err;
+ my $s = Email::Simple->new($msg);
if ($set_headers) {
set_nntp_headers($s->header_obj, $ng, $n, $mid);
if ($set_headers) {
set_nntp_headers($s->header_obj, $ng, $n, $mid);
- $lines = $s->body =~ tr!\n!\n!;
# must be last
$s->body_set('') if ($set_headers == 2);
}
# must be last
$s->body_set('') if ($set_headers == 2);
}
- [ $n, $mid, $s, $bytes, $lines, $ng ];
+ [ $n, $mid, $s, $smsg->bytes, $smsg->lines, $ng ];
}
sub simple_body_write ($$) {
}
sub simple_body_write ($$) {
}
sub search_header_for {
}
sub search_header_for {
- my ($srch, $mid, $field) = @_;
- my $smsg = $srch->lookup_mail($mid) or return;
+ my ($srch, $num, $field) = @_;
+ my $smsg = $srch->lookup_article($num) or return;
my ($self, $xhdr, $field, $range) = @_;
if (defined $range && $range =~ /\A<(.+)>\z/) { # Message-ID
my ($ng, $n) = mid_lookup($self, $1);
my ($self, $xhdr, $field, $range) = @_;
if (defined $range && $range =~ /\A<(.+)>\z/) { # Message-ID
my ($ng, $n) = mid_lookup($self, $1);
- return r430 unless $n;
- my $v = search_header_for($ng->search, $range, $field);
+ return r430 unless defined $n;
+ my $v = search_header_for($ng->search, $n, $field);
hdr_mid_response($self, $xhdr, $ng, $n, $range, $v);
} else { # numeric range
$range = $self->{article} unless defined $range;
hdr_mid_response($self, $xhdr, $ng, $n, $range, $v);
} else { # numeric range
$range = $self->{article} unless defined $range;
more($self, '224 Overview information follows');
long_response($self, $beg, $end, sub {
my ($i) = @_;
more($self, '224 Overview information follows');
long_response($self, $beg, $end, sub {
my ($i) = @_;
- my $mid = $mm->mid_for($$i) or return;
- my $h = search_header_for($srch, $mid, 'references');
- more($self, "$$i $h");
+ my $num = $$i;
+ my $h = search_header_for($srch, $num, 'references');
+ defined $h or return;
+ more($self, "$num $h");
my ($self, $range) = @_;
if ($range && $range =~ /\A<(.+)>\z/) {
my ($ng, $n) = mid_lookup($self, $1);
my ($self, $range) = @_;
if ($range && $range =~ /\A<(.+)>\z/) {
my ($ng, $n) = mid_lookup($self, $1);
- my $smsg = $ng->search->lookup_mail($range) or
- return '430 No article with that message-id';
+ defined $n or return r430;
+ my $smsg = $ng->search->lookup_article($n) or return r430;
more($self, '224 Overview information follows (multi-line)');
# Only set article number column if it's the current group
more($self, '224 Overview information follows (multi-line)');
# Only set article number column if it's the current group
+sub lookup_article {
+ my ($self, $num) = @_;
+ my $term = 'XNUM'.$num;
+ my $smsg;
+ eval {
+ retry_reopen($self, sub {
+ my $db = $self->{skel} || $self->{xdb};
+ my $head = $db->postlist_begin($term);
+ return if $head == $db->postlist_end($term);
+ my $doc_id = $head->get_docid;
+ return unless defined $doc_id;
+ # raises on error:
+ my $doc = $db->get_document($doc_id);
+ $smsg = PublicInbox::SearchMsg->wrap($doc);
+ $smsg->load_expand;
+ $smsg->{doc_id} = $doc_id;
+ });
+ };
+ $smsg;
+}
+
sub each_smsg_by_mid {
my ($self, $mid, $cb) = @_;
my $xdb = $self->{xdb};
sub each_smsg_by_mid {
my ($self, $mid, $cb) = @_;
my $xdb = $self->{xdb};