# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
# based on notmuch, but with no concept of folders, files or flags
#
# License: AGPL-3.0+ <https://www.gnu.org/licenses/agpl-3.0.txt>
# based on notmuch, but with no concept of folders, files or flags
#
use constant YYYYMMDD => 1; # Date: header for searching in the WWW UI
use constant DT => 2; # Date: YYYYMMDDHHMMSS
use constant YYYYMMDD => 1; # Date: header for searching in the WWW UI
use constant DT => 2; # Date: YYYYMMDDHHMMSS
$Xap.'::sortable_unserialise';
# n.b. FLAG_PURE_NOT is expensive not suitable for a public
# website as it could become a denial-of-service vector
$Xap.'::sortable_unserialise';
# n.b. FLAG_PURE_NOT is expensive not suitable for a public
# website as it could become a denial-of-service vector
# or make indexlevel=medium as default
$QP_FLAGS = FLAG_PHRASE() | FLAG_BOOLEAN() | FLAG_LOVEHATE() |
FLAG_WILDCARD();
# or make indexlevel=medium as default
$QP_FLAGS = FLAG_PHRASE() | FLAG_BOOLEAN() | FLAG_LOVEHATE() |
FLAG_WILDCARD();
"$self->{inboxdir}/public-inbox/xapian" . SCHEMA_VERSION;
} else {
my $dir = "$self->{inboxdir}/xap" . SCHEMA_VERSION;
"$self->{inboxdir}/public-inbox/xapian" . SCHEMA_VERSION;
} else {
my $dir = "$self->{inboxdir}/xap" . SCHEMA_VERSION;
my $dir = xdir($self, 1);
my ($xdb, $slow_phrase);
my $qpf = \($self->{qp_flags} ||= $QP_FLAGS);
my $dir = xdir($self, 1);
my ($xdb, $slow_phrase);
my $qpf = \($self->{qp_flags} ||= $QP_FLAGS);
foreach my $shard (<$dir/*>) {
-d $shard && $shard =~ m!/[0-9]+\z! or next;
my $sub = $X{Database}->new($shard);
foreach my $shard (<$dir/*>) {
-d $shard && $shard =~ m!/[0-9]+\z! or next;
my $sub = $X{Database}->new($shard);
}, $class;
my $dir = xdir($self, 1);
$self->{over_ro} = PublicInbox::Over->new("$dir/over.sqlite3");
}, $class;
my $dir = xdir($self, 1);
$self->{over_ro} = PublicInbox::Over->new("$dir/over.sqlite3");
- retry_reopen($self, sub { _enquire_once($self, $query, $opts) });
+ retry_reopen($self, \&_enquire_once, [ $self, $query, $opts ]);
-sub _enquire_once {
- my ($self, $query, $opts) = @_;
+sub _enquire_once { # retry_reopen callback
+ my ($self, $query, $opts) = @{$_[0]};
my $limit = $opts->{limit} || 50;
my $mset = $enquire->get_mset($offset, $limit);
return $mset if $opts->{mset};
my $limit = $opts->{limit} || 50;
my $mset = $enquire->get_mset($offset, $limit);
return $mset if $opts->{mset};
return \@msgs unless wantarray;
($mset->get_matches_estimated, \@msgs)
return \@msgs unless wantarray;
($mset->get_matches_estimated, \@msgs)
# we do not actually create AltId objects,
# just parse the spec to avoid the extra DB handles for now.
if (my $altid = $self->{altid}) {
# we do not actually create AltId objects,
# just parse the spec to avoid the extra DB handles for now.
if (my $altid = $self->{altid}) {
/\Aserial:(\w+):/ or next;
my $pfx = $1;
push @$user_pfx, "$pfx:", <<EOF;
/\Aserial:(\w+):/ or next;
my $pfx = $1;
push @$user_pfx, "$pfx:", <<EOF;