File Coverage

blib/lib/RDF/Query/Algebra/Sequence.pm
Criterion Covered Total %
statement 54 100 54.0
branch 1 8 12.5
condition 3 12 25.0
subroutine 17 26 65.3
pod 13 13 100.0
total 88 159 55.3


line stmt bran cond sub pod time code
1             # RDF::Query::Algebra::Sequence
2             # -----------------------------------------------------------------------------
3              
4             =head1 NAME
5              
6             RDF::Query::Algebra::Sequence - Algebra class for a sequence of algebra operations
7              
8             =head1 VERSION
9              
10             This document describes RDF::Query::Algebra::Sequence version 2.915_01.
11              
12             =cut
13              
14             package RDF::Query::Algebra::Sequence;
15              
16 36     36   177 use strict;
  36         65  
  36         877  
17 36     36   177 use warnings;
  36         61  
  36         912  
18 36     36   175 no warnings 'redefine';
  36         57  
  36         1168  
19 36     36   171 use base qw(RDF::Query::Algebra);
  36         68  
  36         2580  
20              
21 36     36   183 use Data::Dumper;
  36         72  
  36         1645  
22 36     36   184 use Log::Log4perl;
  36         70  
  36         270  
23 36     36   1698 use Scalar::Util qw(refaddr reftype blessed);
  36         74  
  36         2078  
24 36     36   181 use Carp qw(carp croak confess);
  36         77  
  36         2030  
25 36     36   182 use Time::HiRes qw(gettimeofday tv_interval);
  36         72  
  36         246  
26 36     36   3943 use RDF::Trine::Iterator qw(smap swatch);
  36         66  
  36         2622  
27              
28             ######################################################################
29              
30             our ($VERSION);
31             my %AS_SPARQL;
32             BEGIN {
33 36     36   35024 $VERSION = '2.915_01';
34             }
35              
36             ######################################################################
37              
38             =head1 METHODS
39              
40             Beyond the methods documented below, this class inherits methods from the
41             L<RDF::Query::Algebra> class.
42              
43             =over 4
44              
45             =cut
46              
47             =item C<new ( @patterns )>
48              
49             Returns a new Sequence structure.
50              
51             =cut
52              
53             sub new {
54 1     1 1 4 my $class = shift;
55 1         3 my @patterns = @_;
56 1         5 return bless( [ @patterns ] );
57             }
58              
59             =item C<< construct_args >>
60              
61             Returns a list of arguments that, passed to this class' constructor,
62             will produce a clone of this algebra pattern.
63              
64             =cut
65              
66             sub construct_args {
67 1     1 1 3 my $self = shift;
68 1         4 return ($self->patterns);
69             }
70              
71             =item C<< patterns >>
72              
73             Returns a list of patterns belonging to this sequence.
74              
75             =cut
76              
77             sub patterns {
78 2     2 1 4 my $self = shift;
79 2         10 return @$self;
80             }
81              
82             =item C<< sse >>
83              
84             Returns the SSE string for this algebra expression.
85              
86             =cut
87              
88             sub sse {
89 1     1 1 3 my $self = shift;
90 1         2 my $context = shift;
91 1   50     7 my $prefix = shift || '';
92 1   50     4 my $indent = $context->{indent} || ' ';
93            
94 1         5 my @patterns = map { $_->sse( $context ) } $self->patterns;
  2         7  
95 1         9 return sprintf(
96             "(sequence\n${prefix}${indent}%s\n${prefix})",
97             join("\n${prefix}${indent}", @patterns)
98             );
99             }
100              
101             =item C<< as_sparql >>
102              
103             Returns the SPARQL string for this algebra expression.
104              
105             =cut
106              
107             sub as_sparql {
108 0     0 1 0 my $self = shift;
109 0 0       0 if (exists $AS_SPARQL{ refaddr( $self ) }) {
110 0         0 return $AS_SPARQL{ refaddr( $self ) };
111             } else {
112 0         0 my $context = shift;
113             # if (ref($context)) {
114             # $context = { %$context };
115             # }
116 0   0     0 my $indent = shift || '';
117 0         0 my @patterns;
118 0         0 foreach my $t ($self->patterns) {
119 0         0 push(@patterns, $t->as_sparql( $context, $indent ));
120             }
121 0         0 my $string = join(" ;\n${indent}", @patterns);
122 0         0 $AS_SPARQL{ refaddr( $self ) } = $string;
123 0         0 return $string;
124             }
125             }
126              
127             =item C<< as_hash >>
128              
129             Returns the query as a nested set of plain data structures (no objects).
130              
131             =cut
132              
133             sub as_hash {
134 0     0 1 0 my $self = shift;
135 0         0 my $context = shift;
136             return {
137             type => lc($self->type),
138 0         0 patterns => [ map { $_->as_hash } $self->patterns ],
  0         0  
139             };
140             }
141              
142             =item C<< type >>
143              
144             Returns the type of this algebra expression.
145              
146             =cut
147              
148             sub type {
149 0     0 1 0 return 'SEQUENCE';
150             }
151              
152             =item C<< referenced_variables >>
153              
154             Returns a list of the variable names used in this algebra expression.
155              
156             =cut
157              
158             sub referenced_variables {
159 0     0 1 0 my $self = shift;
160 0         0 return RDF::Query::_uniq(map { $_->referenced_variables } $self->patterns);
  0         0  
161             }
162              
163             =item C<< potentially_bound >>
164              
165             Returns a list of the variable names used in this algebra expression that will
166             bind values during execution.
167              
168             =cut
169              
170             sub potentially_bound {
171 0     0 1 0 my $self = shift;
172 0         0 my @patterns = $self->patterns;
173 0         0 return $patterns[ $#patterns ]->potentially_bound;
174             }
175              
176             =item C<< definite_variables >>
177              
178             Returns a list of the variable names that will be bound after evaluating this algebra expression.
179              
180             =cut
181              
182             sub definite_variables {
183 0     0 1 0 my $self = shift;
184 0         0 my @patterns = $self->patterns;
185 0         0 return $patterns[ $#patterns ]->potentially_bound;
186             }
187              
188             =item C<< clone >>
189              
190             =cut
191              
192             sub clone {
193 0     0 1 0 my $self = shift;
194 0         0 my $class = ref($self);
195 0         0 return $class->new( map { $_->clone } $self->patterns );
  0         0  
196             }
197              
198             =item C<< bind_variables ( \%bound ) >>
199              
200             Returns a new algebra pattern with variables named in %bound replaced by their corresponding bound values.
201              
202             =cut
203              
204             sub bind_variables {
205 0     0 1 0 my $self = shift;
206 0         0 my $class = ref($self);
207 0         0 my $bound = shift;
208 0         0 return $class->new( map { $_->bind_variables( $bound ) } $self->patterns );
  0         0  
209             }
210              
211             =item C<< check_duplicate_blanks >>
212              
213             Returns true if blank nodes respect the SPARQL rule of no blank-label re-use
214             across BGPs, otherwise throws a RDF::Query::Error::QueryPatternError exception.
215              
216             =cut
217              
218             sub check_duplicate_blanks {
219 1     1 1 2 my $self = shift;
220 1         3 my @data;
221 1 50 33     5 foreach my $arg (grep { blessed($_) and $_->isa('RDF::Query::Algebra::Update') and $_->data_only } $self->construct_args) {
  2         27  
222 0         0 push(@data, [$arg, $arg->_referenced_blanks()]);
223             }
224            
225 1         4 my %seen;
226 1         2 foreach my $d (@data) {
227 0         0 my ($pat, $data) = @$d;
228 0         0 foreach my $b (@$data) {
229 0 0       0 if ($seen{ $b }) {
230 0         0 throw RDF::Query::Error::QueryPatternError -text => "Same blank node identifier ($b) used in more than one BasicGraphPattern.";
231             }
232 0         0 $seen{ $b } = $pat;
233             }
234             }
235            
236 1         4 return 1;
237             }
238              
239             sub _referenced_blanks {
240 0     0   0 my $self = shift;
241 0         0 my @data;
242 0         0 foreach my $arg ($self->pattern) {
243 0 0 0     0 if (blessed($arg) and $arg->isa('RDF::Query::Algebra')) {
244 0         0 push( @data, $arg->_referenced_blanks );
245             }
246             }
247 0         0 return @data;
248             }
249              
250             sub DESTROY {
251 1     1   607 my $self = shift;
252 1         11 delete $AS_SPARQL{ refaddr( $self ) };
253             }
254              
255             1;
256              
257             __END__
258              
259             =back
260              
261             =head1 AUTHOR
262              
263             Gregory Todd Williams <gwilliams@cpan.org>
264              
265             =cut