blob: 995358f83ff1728138396a0e20035e5f5b2a1a4c [file] [log] [blame]
Akron0a0e9242016-10-28 14:42:29 +02001package Krawfish::Koral::Query;
Akron6621e112016-11-05 17:21:39 +01002use parent 'Krawfish::Info';
Akron4763ea62016-11-02 19:36:18 +01003use Krawfish::Koral::Query::Builder;
Akron944091b2016-11-24 16:40:58 +01004use Krawfish::Koral::Query::Importer;
Akron965f5d92017-01-20 18:38:08 +01005use Mojo::Util qw/md5_sum/;
Akron0a0e9242016-10-28 14:42:29 +02006use warnings;
Akron944091b2016-11-24 16:40:58 +01007use strict;
Akron0a0e9242016-10-28 14:42:29 +02008
Akron33f1dcb2016-10-29 17:27:23 +02009sub new {
10 my $class = shift;
Akron944091b2016-11-24 16:40:58 +010011 my $self = bless {
Akron4763ea62016-11-02 19:36:18 +010012 any => 0,
13 optional => 0,
14 null => 0,
15 negative => 0,
16 extended => 0,
Akronddf077a2016-11-05 15:00:00 +010017 extended_left => 0,
Akron6621e112016-11-05 17:21:39 +010018 extended_right => 0
Akron4763ea62016-11-02 19:36:18 +010019 }, $class;
Akron944091b2016-11-24 16:40:58 +010020
21 if ($_[0]) {
22 return $self->from_koral(shift);
23 };
24
25 $self;
Akron33f1dcb2016-10-29 17:27:23 +020026};
27
Akron4763ea62016-11-02 19:36:18 +010028#########################################
29# Query Planning methods and attributes #
30#########################################
Akrona211bf52016-10-29 18:03:29 +020031
Akron4763ea62016-11-02 19:36:18 +010032# Prepare a query for an index
Akron6a749732017-02-14 14:43:06 +010033# TODO: Rename to compile()
Akron4763ea62016-11-02 19:36:18 +010034sub prepare_for {
35 my ($self, $index) = @_;
Akronc3657bf2016-10-31 00:15:43 +010036
Akron4763ea62016-11-02 19:36:18 +010037 my $query = $self;
38
39 # There is a possible 'any' extension,
40 # that may exceed the text
41 if ($self->is_extended_right) {
42 my $builder = $self->builder;
43
44 # Wrap query in a text element
45 $query = $builder->position(
46 ['endsWith', 'isAround', 'startsWith', 'matches'],
47 $builder->span('base/s=t'),
48 $self
49 );
50 };
51
52 # Return the planned query
53 # TODO: Check for serialization errors
54 $query->plan_for($index);
55};
56
57# Plan a query for an index (to be overwritten)
Akron349747d2016-12-05 11:05:53 +010058# TODO: Rename to_primitive(index)
Akron4763ea62016-11-02 19:36:18 +010059sub plan_for;
60
Akron22b68582017-01-19 12:05:21 +010061# Filter a query based on a document query
62sub filter_by;
63
Akrondc9f1162016-11-05 15:31:40 +010064sub is_any { $_[0]->{any} // 0 };
65sub is_optional { $_[0]->{optional} // 0 };
66sub is_null { $_[0]->{null} // 0 };
67sub is_negative { $_[0]->{negative} // 0 };
Akrondc9f1162016-11-05 15:31:40 +010068sub is_extended_right { $_[0]->{extended_right} // 0 };
69sub is_extended_left { $_[0]->{extended_left} // 0 };
Akron84b8b752016-11-19 15:55:12 +010070sub is_extended { $_[0]->is_extended_right || $_[0]->is_extended_left // 0 };
Akron4763ea62016-11-02 19:36:18 +010071sub freq { -1 };
Akron774c5db2016-11-09 16:11:38 +010072sub type { '' };
Akrona211bf52016-10-29 18:03:29 +020073
Akron774c5db2016-11-09 16:11:38 +010074# TODO: Probably better to be renamed "potential_anchor"
Akrona211bf52016-10-29 18:03:29 +020075sub maybe_anchor {
76 my $self = shift;
77 return if $self->is_negative;
78 return if $self->is_optional;
79 return if $self->is_any;
80 return 1;
81};
82
83# Check if the wrapped query may need to be sorted
84# on focussing on a specific class.
85# Normally spans are always sorted, but in case of
86# a wrapped relation query, classed operands may
87# be in arbitrary order. When focussing on these
88# classes, the span has to me reordered.
Akron1b09c5b2016-11-20 15:59:34 +010089sub maybe_unsorted { $_[0]->{maybe_unsorted} // 0 };
Akrona211bf52016-10-29 18:03:29 +020090
Akron965f5d92017-01-20 18:38:08 +010091
92# Iterate over all subqueries and possibly replace them
93sub subqueries;
94
Akrona211bf52016-10-29 18:03:29 +020095#############################
96# Query Application methods #
97#############################
Akron33f1dcb2016-10-29 17:27:23 +020098
Akrona211bf52016-10-29 18:03:29 +020099# Deserialization of KoralQuery
Akron944091b2016-11-24 16:40:58 +0100100# TODO: export this method from Importer
Akron33f1dcb2016-10-29 17:27:23 +0200101sub from_koral {
Akron944091b2016-11-24 16:40:58 +0100102 my ($class, $kq) = @_;
103 my $importer = Krawfish::Koral::Query::Importer->new;
104
105 my $type = $kq->{'@type'};
106 if ($type eq 'koral:group') {
107 my $op = $kq->{operation};
108 if ($op eq 'operation:sequence') {
109 return $importer->seq($kq);
110 }
111
112 elsif ($op eq 'operation:class') {
113 return $importer->class($kq);
114 }
115 else {
116 warn 'Operation ' . $op . ' not supported';
117 };
118 }
119
120 elsif ($type eq 'koral:token') {
121 return $importer->token($kq);
122 }
123 else {
124 warn $type . ' unknown';
125 };
126
127 return;
Akron33f1dcb2016-10-29 17:27:23 +0200128};
129
Akrona211bf52016-10-29 18:03:29 +0200130# Overwritten
131sub to_koral_fragment;
132
Akronc3657bf2016-10-31 00:15:43 +0100133# Overwritten
Akrona211bf52016-10-29 18:03:29 +0200134sub to_string;
Akron33f1dcb2016-10-29 17:27:23 +0200135
Akron965f5d92017-01-20 18:38:08 +0100136# TODO: This may be optimizable and
137# implemented in all query and corpus wrappers
138sub to_signature {
139 md5_sum $_[0]->to_string;
140};
141
142# TODO: Returns a value of complexity of the query,
143# that can be used to decide, if a query should be cached.
144sub complexity;
145
Akron573e7ec2016-11-05 19:03:01 +0100146# Clone the query
147# sub clone;
Akronc3657bf2016-10-31 00:15:43 +0100148
Akron4763ea62016-11-02 19:36:18 +0100149# Create KoralQuery builder
150sub builder {
151 return Krawfish::Koral::Query::Builder->new;
152};
153
Akron944091b2016-11-24 16:40:58 +0100154# Create KoralQuery builder
155sub importer {
156 return Krawfish::Koral::Query::Importer->new;
157};
158
Akron169ede42017-02-05 12:52:22 +0100159
160# Serialization helper
161sub boundary {
162 my $self = shift;
163 my %hash = (
164 '@type' => 'koral:boundary'
165 );
166 $hash{min} = $self->{min} if defined $self->{min};
167 $hash{max} = $self->{max} if defined $self->{max};
168 return \%hash;
169}
170
171
Akron0a0e9242016-10-28 14:42:29 +02001721;
Akron33f1dcb2016-10-29 17:27:23 +0200173
Akrona211bf52016-10-29 18:03:29 +0200174
Akron33f1dcb2016-10-29 17:27:23 +0200175__END__
176