File Coverage

blib/lib/Attean/API/Expression.pm
Criterion Covered Total %
statement 57 87 65.5
branch n/a
condition 1 4 25.0
subroutine 17 25 68.0
pod 0 13 0.0
total 75 129 58.1


line stmt bran cond sub pod time code
1 50     50   633 use v5.14;
  50         163  
2 50     50   263 use warnings;
  50         92  
  50         2540  
3              
4             =head1 NAME
5              
6             Attean::API::Expression - SPARQL expressions
7              
8             =head1 VERSION
9              
10             This document describes Attean::API::Expression version 0.032
11              
12             =head1 DESCRIPTION
13              
14             The Attean::API::Expression role defines a common API for SPARQL expressions
15             consisting of logical, numeric, and function operators, constant terms, and
16             variables. Expressions may be evaluated in the context of a
17             L<Attean::API::Result> object, and either return a L<Attean::API::Term> object
18             or throw a type error exception.
19              
20             =head1 ROLES
21              
22             This role consumes the L<Attean::API::DirectedAcyclicGraph> role which provide the following methods:
23              
24             =over 4
25              
26             =item C<< is_leaf >>
27              
28             =item C<< walk( prefix => \&pre_cb, postfix => \&pre_cb ) >>
29              
30             =item C<< cover( prefix => \&pre_cb, postfix => \&pre_cb ) >>
31              
32             =back
33              
34             and the following attributes:
35              
36             =over 4
37              
38             =item C<< children >>
39              
40             =back
41              
42             =head1 ATTRIBUTES
43              
44             The following attributes exist:
45              
46             =over 4
47              
48             =item C<< operator >>
49              
50             A string indicating the expression operator (e.g. C<'+'> or C<'||'>).
51              
52             =back
53              
54             =head1 REQUIRED METHODS
55              
56             The following methods are required by the L<Attean::API::Expression> role:
57              
58             =over 4
59              
60             =item C<< as_string >>
61              
62             Returns a string serialization of the expression object.
63              
64             =back
65              
66             =cut
67              
68             use Types::Standard qw(Str);
69 50     50   285  
  50         112  
  50         383  
70             use Moo::Role;
71 50     50   34648  
  50         104  
  50         298  
72             with 'Attean::API::DirectedAcyclicGraph', 'Attean::API::UnionScopeVariables';
73            
74             has 'operator' => (is => 'ro', isa => Str, required => 1);
75             requires 'is_stable'; # is stable for sorting (won't change across evaluations)
76             requires 'unaggregated_variables';
77             requires 'as_string';
78             requires 'as_sparql';
79            
80             if ($ENV{ATTEAN_TYPECHECK}) {
81       1440 0   around 'BUILD' => sub {
82             my $orig = shift;
83             my $self = shift;
84             $self->$orig(@_);
85             my $name = ref($self);
86             $name =~ s/^.*://;
87             if ($self->can('arity')) {
88             my $arity = $self->arity;
89             if (defined($arity)) {
90             my $children = $self->children;
91             my $size = scalar(@$children);
92             unless ($size == $arity) {
93             die "${name} expression construction with bad number of children (expected $arity, but got $size)";
94             }
95             }
96             }
97             }
98             }
99             }
100              
101             use AtteanX::SPARQL::Constants;
102             use AtteanX::SPARQL::Token;
103              
104 50     50   24698 use Moo::Role;
  50         113  
  50         7598  
105 50     50   302
  50         93  
  50         851  
106             with 'Attean::API::Expression', 'Attean::API::UnaryQueryTree';
107 50     50   206 with 'Attean::API::SPARQLSerializable';
  50         87  
  50         181  
108            
109             my $self = shift;
110             my ($data) = @{ $self->children };
111             return sprintf("%s(%s)", $self->operator, $data->as_string);
112             }
113 2     2 0 294  
114 2         5 my %ops = (
  2         6  
115 2         8 '!' => AtteanX::SPARQL::Token->fast_constructor( BANG, -1, -1, -1, -1, ['!'] ),
116             '-' => AtteanX::SPARQL::Token->fast_constructor( MINUS, -1, -1, -1, -1, ['-'] ),
117             '+' => AtteanX::SPARQL::Token->fast_constructor( PLUS, -1, -1, -1, -1, ['+'] ),
118             );
119              
120             my $self = shift;
121             my ($child) = @{ $self->children };
122             return $child->unaggregated_variables;
123             }
124            
125 0     0 0 0 my $self = shift;
126 0         0 my $op = $ops{$self->operator} // die "No operator found in Attean::API::UnaryExpression->sparql_tokens";
  0         0  
127 0         0  
128             my @tokens;
129             push(@tokens, $op);
130             foreach my $t (@{ $self->children }) {
131 0     0 0 0 push(@tokens, $t->sparql_tokens->elements);
132 0   0     0 }
133             return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
134 0         0 }
135 0         0 }
136 0         0  
  0         0  
137 0         0 use AtteanX::SPARQL::Constants;
138             use AtteanX::SPARQL::Token;
139 0         0  
140             use Moo::Role;
141            
142             with 'Attean::API::Expression', 'Attean::API::BinaryQueryTree';
143             with 'Attean::API::SPARQLSerializable';
144 50     50   26486  
  50         148  
  50         7130  
145 50     50   368 my $self = shift;
  50         110  
  50         938  
146             my ($lhs, $rhs) = @{ $self->children };
147 50     50   235 return sprintf("(%s %s %s)", $lhs->as_string, $self->operator, $rhs->as_string);
  50         109  
  50         259  
148             }
149              
150             my $self = shift;
151             return map { $_->unaggregated_variables } @{ $self->children };
152             }
153 4     4 0 316
154 4         7 my %ops = (
  4         17  
155 4         19 '-' => AtteanX::SPARQL::Token->fast_constructor( MINUS, -1, -1, -1, -1, ['-'] ),
156             '+' => AtteanX::SPARQL::Token->fast_constructor( PLUS, -1, -1, -1, -1, ['+'] ),
157             '*' => AtteanX::SPARQL::Token->fast_constructor( STAR, -1, -1, -1, -1, ['*'] ),
158             '/' => AtteanX::SPARQL::Token->fast_constructor( SLASH, -1, -1, -1, -1, ['/'] ),
159 0     0 0 0 '<' => AtteanX::SPARQL::Token->fast_constructor( LT, -1, -1, -1, -1, ['<'] ),
160 0         0 '>' => AtteanX::SPARQL::Token->fast_constructor( GT, -1, -1, -1, -1, ['>'] ),
  0         0  
  0         0  
161             '<=' => AtteanX::SPARQL::Token->fast_constructor( LE, -1, -1, -1, -1, ['<='] ),
162             '>=' => AtteanX::SPARQL::Token->fast_constructor( GE, -1, -1, -1, -1, ['>='] ),
163             '!=' => AtteanX::SPARQL::Token->fast_constructor( NOTEQUALS, -1, -1, -1, -1, ['!='] ),
164             '=' => AtteanX::SPARQL::Token->fast_constructor( EQUALS, -1, -1, -1, -1, ['='] ),
165             '&&' => AtteanX::SPARQL::Token->fast_constructor( ANDAND, -1, -1, -1, -1, ['&&'] ),
166             '||' => AtteanX::SPARQL::Token->fast_constructor( OROR, -1, -1, -1, -1, ['||'] ),
167             );
168            
169             my $self = shift;
170             my $op = $ops{$self->operator} // die "No operator found in Attean::API::BinaryExpression->sparql_tokens";
171              
172             my @tokens;
173             foreach my $t (@{ $self->children }) {
174             push(@tokens, $t->sparql_tokens->elements);
175             push(@tokens, $op);
176             }
177             pop(@tokens);
178             return Attean::ListIterator->new( values => \@tokens, item_type => 'AtteanX::SPARQL::Token' );
179 7     7 0 9 }
180 7   50     30 }
181              
182 7         12 use Moo::Role;
183 7         11 with 'Attean::API::Expression', 'Attean::API::QueryTree';
  7         17  
184 14         55 my $self = shift;
185 14         40 my @children = map { $_->as_string } @{ $self->children };
186             return sprintf("%s(%s)", $self->operator, join(', ', @children));
187 7         16 }
188 7         106  
189             my $self = shift;
190             return $self->as_string;
191             }
192              
193 50     50   35759 my $self = shift;
  50         121  
  50         257  
194             return map { $_->unaggregated_variables } @{ $self->children };
195             }
196 1     1 0 854 }
197 1         2  
  2         6  
  1         5  
198 1         9 use Moo::Role;
199             requires 'operator';
200             requires 'scalar_vars';
201             with 'Attean::API::Expression', 'Attean::API::DirectedAcyclicGraph';
202 0     0 0    
203 0           my $self = shift;
204             my @children = map { $_->as_string } @{ $self->children };
205             return sprintf("%s(%s)", $self->operator, join(', ', @children));
206             }
207 0     0 0    
208 0           my $self = shift;
  0            
  0            
209             return $self->as_string;
210             }
211              
212             return;
213 50     50   22998 }
  50         118  
  50         240  
214             }
215              
216             1;
217              
218              
219 0     0 0   =head1 BUGS
220 0            
  0            
  0            
221 0           Please report any bugs or feature requests to through the GitHub web interface
222             at L<https://github.com/kasei/attean/issues>.
223              
224             =head1 SEE ALSO
225 0     0 0    
226 0            
227              
228             =head1 AUTHOR
229              
230 0     0 0   Gregory Todd Williams C<< <gwilliams@cpan.org> >>
231              
232             =head1 COPYRIGHT
233              
234             Copyright (c) 2014--2022 Gregory Todd Williams.
235             This program is free software; you can redistribute it and/or modify it under
236             the same terms as Perl itself.
237              
238             =cut