Catmandu-Store-OpenSearch
view release on metacpan or search on metacpan
lib/Catmandu/Store/OpenSearch/CQL.pm view on Meta::CPAN
package Catmandu::Store::OpenSearch::CQL;
use Catmandu::Sane;
our $VERSION = '0.03';
use Catmandu::Util qw(require_package trim);
use CQL::Parser;
use Moo;
use Types::Standard qw(HashRef);
use Types::Common::String qw(NonEmptyStr);
use namespace::clean;
use feature qw(signatures);
no warnings qw(experimental::signatures);
has parser => (is => 'lazy', init_arg => undef);
has mapping => (is => 'ro', isa => HashRef, required => 1);
has id_key => (is => 'ro', isa => NonEmptyStr, required => 1);
my $RE_ANY_FIELD = qr'^(srw|cql)\.(serverChoice|anywhere)$'i;
my $RE_MATCH_ALL = qr'^(srw|cql)\.allRecords$'i;
my $RE_DISTANCE_MODIFIER = qr'\s*\/\s*distance\s*<\s*(\d+)'i;
sub _build_parser {
CQL::Parser->new;
}
sub parse ($self, $query) {
my $node = eval {$self->parser->parse($query);} or do {
my $error = $@;
die("cql error: $error");
};
$self->parse_node($node);
}
sub parse_node ($self, $node) {
my $query = {};
if ($node->isa('CQL::TermNode')) {
$self->_parse_term_node($node, $query);
return $query;
}
elsif ($node->isa('CQL::ProxNode')) {
$self->_parse_prox_node($node, $query);
return $query;
}
my @stack = ($node);
my @query_stack = (my $q = $query);
while (@stack) {
$node = shift @stack;
$q = shift @query_stack;
if ($node->isa('CQL::ProxNode')) { # CQL::ProxNode is a subclass of CQL::BooleanNode
$self->_parse_prox_node($node, $q);
}
elsif ($node->isa('CQL::BooleanNode')) {
push @stack, $node->left, $node->right;
push @query_stack, my $left = {}, my $right = {};
if ($node->op eq 'and') {
$q->{bool} = {must => [$left, $right]};
}
elsif ($node->op eq 'or') {
$q->{bool} = {should => [$left, $right]};
}
else {
$q->{bool} = {must => [$left, {bool => {must_not => [$right]}}]};
}
}
elsif ($node->isa('CQL::TermNode')) {
$self->_parse_term_node($node, $q);
}
else {
Catmandu::Error->throw('cql error: unable to map node of class '.ref($node));
}
}
( run in 2.361 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )