package PublicInbox::Xapcmd;
use strict;
use warnings;
-use PublicInbox::Spawn qw(which spawn);
+use PublicInbox::Spawn qw(which popen_rd);
use PublicInbox::Over;
-use PublicInbox::Search;
-use File::Temp ();
+use PublicInbox::SearchIdx;
+use File::Temp 0.19 (); # ->newdir
use File::Path qw(remove_tree);
use File::Basename qw(dirname);
use POSIX ();
sub prepare_reindex ($$$) {
my ($ibx, $im, $reindex) = @_;
- if ($ibx->{version} == 1) {
+ if ($ibx->version == 1) {
my $dir = $ibx->search->xdir(1);
- my $xdb = Search::Xapian::Database->new($dir);
+ my $xdb = $PublicInbox::Search::X{Database}->new($dir);
if (my $lc = $xdb->get_metadata('last_commit')) {
$reindex->{from} = $lc;
}
if (!$opt->{-coarse_lock}) {
$reindex = $opt->{reindex} = {};
$from = $reindex->{from} = [];
- require Search::Xapian::WritableDatabase;
+ require PublicInbox::SearchIdx;
+ PublicInbox::SearchIdx::load_xapian_writable();
}
$ibx->umask_prepare;
-d $old or die "$old does not exist\n";
my $tmp = {};
- my $v = $ibx->{version} ||= 1;
my @q;
my $reshard = $opt->{reshard};
if (defined $reshard && $reshard <= 0) {
# we want temporary directories to be as deep as possible,
# so v2 shards can keep "xap$SCHEMA_VERSION" on a separate FS.
- if ($v == 1) {
+ if ($ibx->version == 1) {
if (defined $reshard) {
warn
"--reshard=$reshard ignored for v1 $ibx->{inboxdir}\n";
sub cpdb_retryable ($$) {
my ($src, $pfx) = @_;
- if (ref($@) eq 'Search::Xapian::DatabaseModifiedError') {
+ if (ref($@) =~ /\bDatabaseModifiedError\b/) {
warn "$pfx Xapian DB modified, reopening and retrying\n";
$src->reopen;
return 1;
my ($args, $opt) = @_;
my ($src, $newdir) = @$args;
my $dst = ref($newdir) ? $newdir->dirname : $newdir;
- my ($r, $w);
my $pfx = $opt->{-progress_pfx} ||= progress_pfx($src);
my $pr = $opt->{-progress};
my $rdr = {};
defined(my $dfd = $opt->{$fd}) or next;
$rdr->{$fd} = $dfd;
}
- $rdr->{1} = fileno($w) if $pr && pipe($r, $w);
# we rely on --no-renumber to keep docids synched to NNTP
my $cmd = [ $XAPIAN_COMPACT, '--no-renumber' ];
}
$pr->("$pfx `".join(' ', @$cmd)."'\n") if $pr;
push @$cmd, $src, $dst;
- my $pid = spawn($cmd, undef, $rdr);
- if ($pr) {
- close $w or die "close: \$w: $!";
- foreach (<$r>) {
+ my $rd = popen_rd($cmd, undef, $rdr);
+ while (<$rd>) {
+ if ($pr) {
s/\r/\r$pfx /g;
$pr->("$pfx $_");
}
}
- my $rp = waitpid($pid, 0);
- if ($? || $rp != $pid) {
- die join(' ', @$cmd)." failed: $? (pid=$pid, reaped=$rp)\n";
- }
+ close $rd or die join(' ', @$cmd)." failed: $?n";
}
sub cpdb_loop ($$$;$$) {
my $new = $newdir->dirname;
my ($src, $cur_shard);
my $reshard;
+ PublicInbox::SearchIdx::load_xapian_writable() or die;
+ my $XapianDatabase = $PublicInbox::Search::X{Database};
if (ref($old) eq 'ARRAY') {
($cur_shard) = ($new =~ m!xap[0-9]+/([0-9]+)\b!);
defined $cur_shard or
# resharding, M:N copy means have full read access
foreach (@$old) {
if ($src) {
- my $sub = Search::Xapian::Database->new($_);
+ my $sub = $XapianDatabase->new($_);
$src->add_database($sub);
} else {
- $src = Search::Xapian::Database->new($_);
+ $src = $XapianDatabase->new($_);
}
}
} else {
- $src = Search::Xapian::Database->new($old);
+ $src = $XapianDatabase->new($old);
}
my ($tmp, $ft);
# like copydatabase(1), be sure we don't overwrite anything in case
# of other bugs:
- my $creat = Search::Xapian::DB_CREATE();
- my $dst = Search::Xapian::WritableDatabase->new($tmp, $creat);
+ my $creat = eval($PublicInbox::Search::Xap.'::DB_CREATE()');
+ die if $@;
+ my $XapianWritableDatabase = $PublicInbox::Search::X{WritableDatabase};
+ my $dst = $XapianWritableDatabase->new($tmp, $creat);
my $pr = $opt->{-progress};
my $pfx = $opt->{-progress_pfx} = progress_pfx($new);
my $pr_data = { pr => $pr, pfx => $pfx, nr => 0 } if $pr;
# individually.
$src = undef;
foreach (@$old) {
- my $old = Search::Xapian::Database->new($_);
+ my $old = $XapianDatabase->new($_);
cpdb_loop($old, $dst, $pr_data, $cur_shard, $reshard);
}
} else {