use PublicInbox::MID qw/mid_clean id_compress mid_mime/;
use PublicInbox::MsgIter;
use Carp qw(croak);
+use POSIX qw(strftime);
require PublicInbox::Git;
*xpfx = *PublicInbox::Search::xpfx;
};
sub new {
- my ($class, $git_dir, $creat) = @_;
+ my ($class, $inbox, $creat) = @_;
+ my $git_dir = $inbox;
+ my $altid;
+ if (ref $inbox) {
+ $git_dir = $inbox->{mainrepo};
+ $altid = $inbox->{altid};
+ if ($altid) {
+ require PublicInbox::AltId;
+ $altid = [ map {
+ PublicInbox::AltId->new($inbox, $_);
+ } @$altid ];
+ }
+ }
require Search::Xapian::WritableDatabase;
- my $self = bless { git_dir => $git_dir }, $class;
+ my $self = bless { git_dir => $git_dir, -altid => $altid }, $class;
my $perm = $self->_git_config_perm;
my $umask = _umask_for($perm);
$self->{umask} = $umask;
close $lockfh or die "close failed: $!\n";
}
-sub add_val {
+sub add_val ($$$) {
my ($doc, $col, $num) = @_;
$num = Search::Xapian::sortable_serialise($num);
$doc->add_value($col, $num);
}
+sub add_values ($$$) {
+ my ($smsg, $bytes, $num) = @_;
+
+ my $ts = $smsg->ts;
+ my $doc = $smsg->{doc};
+ add_val($doc, &PublicInbox::Search::TS, $ts);
+
+ defined($num) and add_val($doc, &PublicInbox::Search::NUM, $num);
+
+ defined($bytes) and add_val($doc, &PublicInbox::Search::BYTES, $bytes);
+
+ add_val($doc, &PublicInbox::Search::LINES,
+ $smsg->{mime}->body_raw =~ tr!\n!\n!);
+
+ my $yyyymmdd = strftime('%Y%m%d', gmtime($ts));
+ $doc->add_value(&PublicInbox::Search::YYYYMMDD, $yyyymmdd);
+}
+
+sub index_users ($$) {
+ my ($tg, $smsg) = @_;
+
+ my $from = $smsg->from;
+ my $to = $smsg->to;
+ my $cc = $smsg->cc;
+
+ $tg->index_text($from, 1, 'A'); # A - author
+ $tg->increase_termpos;
+
+ $tg->index_text($to, 1, 'XTO') if $to ne '';
+ $tg->index_text($cc, 1, 'XCC') if $cc ne '';
+ my $tc = join("\t", $to, $cc);
+ $tg->index_text($tc, 1, 'XTC') if $tc ne '';
+ my $tcf = join("\t", $tc, $from);
+ $tg->index_text($tcf, 1, 'XTCF') if $tcf ne '';
+
+ $tg->index_text($from);
+ $tg->increase_termpos;
+}
+
sub add_message {
my ($self, $mime, $bytes, $num, $blob) = @_; # mime = Email::MIME object
my $db = $self->{xdb};
$doc->add_term(xpfx('path') . id_compress($path));
}
- add_val($doc, &PublicInbox::Search::TS, $smsg->ts);
-
- defined($num) and
- add_val($doc, &PublicInbox::Search::NUM, $num);
-
- defined($bytes) and
- add_val($doc, &PublicInbox::Search::BYTES, $bytes);
-
- add_val($doc, &PublicInbox::Search::LINES,
- $mime->body_raw =~ tr!\n!\n!);
+ add_values($smsg, $bytes, $num);
my $tg = $self->term_generator;
$tg->index_text($subj) if $subj;
$tg->increase_termpos;
- $tg->index_text($smsg->from);
- $tg->increase_termpos;
+ index_users($tg, $smsg);
msg_iter($mime, sub {
my ($part, $depth, @idx) = @{$_[0]};
});
link_message($self, $smsg, $old_tid);
+ $tg->index_text($mid, 1);
$doc->set_data($smsg->to_doc_data($blob));
+
+ if (my $altid = $self->{-altid}) {
+ foreach my $alt (@$altid) {
+ my $id = $alt->mid2alt($mid);
+ next unless defined $id;
+ $doc->add_term($alt->{xprefix} . $id);
+ }
+ }
if (defined $doc_id) {
$db->replace_document($doc_id, $doc);
} else {
my $mm = _msgmap_init($self);
my $dbh = $mm->{dbh} if $mm;
+ my $mm_only;
my $cb = sub {
my ($commit, $more) = @_;
if ($dbh) {
$mm->last_commit($commit) if $commit;
$dbh->commit;
}
- $xdb->set_metadata($mkey, $commit) if $mkey && $commit;
- $xdb->commit_transaction;
- $xdb = _xdb_release($self);
+ if (!$mm_only) {
+ $xdb->set_metadata($mkey, $commit) if $mkey && $commit;
+ $xdb->commit_transaction;
+ $xdb = _xdb_release($self);
+ }
# let another process do some work... <
if ($more) {
- $xdb = _xdb_acquire($self);
- $xdb->begin_transaction;
+ if (!$mm_only) {
+ $xdb = _xdb_acquire($self);
+ $xdb->begin_transaction;
+ }
$dbh->begin_work if $dbh;
}
};
my $mkey_prev = $mkey;
$mkey = undef; # ignore xapian, for now
my $mlog = _git_log($self, $r);
+ $mm_only = 1;
rlog($self, $mlog, *index_mm, *unindex_mm, $cb);
- $mlog = undef;
+ $mm_only = $mlog = undef;
# now deal with Xapian
$mkey = $mkey_prev;
$dbh = undef;
- $xdb = _xdb_acquire($self);
- $xdb->begin_transaction;
rlog($self, $xlog, *index_mm2, *unindex_mm2, $cb);
}
} else {