-sub reopen { $_[0]->{xdb}->reopen }
-
-sub add_message {
- my ($self, $mime) = @_; # mime = Email::MIME object
- my $db = $self->{xdb};
-
- my $doc_id;
- my $mid_orig = mid_clean($mime->header_obj->header_raw('Message-ID'));
- my $mid = mid_compressed($mid_orig);
- my $was_ghost = 0;
- my $ct_msg = $mime->header('Content-Type') || 'text/plain';
- my $enc_msg = PublicInbox::View::enc_for($ct_msg);
-
- eval {
- my $smsg = $self->lookup_message($mid);
- my $doc;
-
- if ($smsg) {
- $smsg->ensure_metadata;
- # convert a ghost to a regular message
- # it will also clobber any existing regular message
- $smsg->mime($mime);
- $doc = $smsg->{doc};
-
- my $type = xpfx('type');
- eval {
- $doc->remove_term($type . 'ghost');
- $was_ghost = 1;
- };
-
- # probably does not exist:
- eval { $doc->remove_term($type . 'mail') };
- $doc->add_term($type . 'mail');
- } else {
- $smsg = PublicInbox::SearchMsg->new($mime);
- $doc = $smsg->{doc};
- $doc->add_term(xpfx('mid') . $mid);
- }
-
- my $subj = $smsg->subject;
-
- if (length $subj) {
- $doc->add_term(xpfx('subject') . $subj);
-
- my $path = subject_path($subj);
- $doc->add_term(xpfx('path') . mid_compressed($path));
- }
-
- my $from = $smsg->from_name;
- my $date = $smsg->date;
- my $ts = Search::Xapian::sortable_serialise($smsg->ts);
- $doc->add_value(PublicInbox::Search::TS, $ts);
-
- $doc->set_data($smsg->to_doc_data);
-
- my $tg = $self->term_generator;
-
- $tg->set_document($doc);
- $tg->index_text($subj, 1, 'S') if $subj;
- $tg->increase_termpos;
- $tg->index_text($subj) if $subj;
- $tg->increase_termpos;
-
- $tg->index_text($smsg->from->format);
- $tg->increase_termpos;
-
- $mime->walk_parts(sub {
- my ($part) = @_;
- return if $part->subparts; # walk_parts already recurses
- my $ct = $part->content_type || $ct_msg;
-
- # account for filter bugs...
- $ct =~ m!\btext/plain\b!i or return;
-
- my $enc = PublicInbox::View::enc_for($ct, $enc_msg);
- my (@orig, @quot);
- foreach my $l (split(/\n/, $enc->decode($part->body))) {
- if ($l =~ /^\s*>/) {
- push @quot, $l;
- } else {
- push @orig, $l;
- }
- }
- if (@quot) {
- $tg->index_text(join("\n", @quot), 0);
- $tg->increase_termpos;
- }
- if (@orig) {
- $tg->index_text(join("\n", @orig));
- $tg->increase_termpos;
+sub new {
+ my ($class, $mainrepo, $altid) = @_;
+ my $version = 1;
+ my $ibx = $mainrepo;
+ if (ref $ibx) {
+ $version = $ibx->{version} || 1;
+ $mainrepo = $ibx->{mainrepo};
+ }
+ my $self = bless {
+ mainrepo => $mainrepo,
+ altid => $altid,
+ version => $version,
+ }, $class;
+ my $dir;
+ if ($version >= 2) {
+ $dir = "$self->{mainrepo}/xap" . SCHEMA_VERSION;
+ my $xdb;
+ my $parts = 0;
+ foreach my $part (<$dir/*>) {
+ -d $part && $part =~ m!/\d+\z! or next;
+ $parts++;
+ my $sub = Search::Xapian::Database->new($part);
+ if ($xdb) {
+ $xdb->add_database($sub);
+ } else {
+ $xdb = $sub;