File Coverage

blib/lib/RDF/Query/Algebra/NamedGraph.pm
Criterion Covered Total %
statement 73 125 58.4
branch 1 12 8.3
condition 4 12 33.3
subroutine 20 27 74.0
pod 16 16 100.0
total 114 192 59.3


line stmt bran cond sub pod time code
1             # RDF::Query::Algebra::NamedGraph
2             # -----------------------------------------------------------------------------
3              
4             =head1 NAME
5              
6             RDF::Query::Algebra::NamedGraph - Algebra class for NamedGraph patterns
7              
8             =head1 VERSION
9              
10             This document describes RDF::Query::Algebra::NamedGraph version 2.915_01.
11              
12             =cut
13              
14             package RDF::Query::Algebra::NamedGraph;
15              
16 36     36   179 use strict;
  36         65  
  36         906  
17 36     36   170 use warnings;
  36         71  
  36         909  
18 36     36   173 no warnings 'redefine';
  36         59  
  36         1149  
19 36     36   249 use base qw(RDF::Query::Algebra);
  36         63  
  36         2548  
20              
21 36     36   187 use Data::Dumper;
  36         76  
  36         1625  
22 36     36   180 use Log::Log4perl;
  36         65  
  36         239  
23 36     36   1484 use RDF::Query::Error;
  36         72  
  36         329  
24 36     36   1757 use Carp qw(carp croak confess);
  36         72  
  36         2070  
25 36     36   184 use Scalar::Util qw(blessed reftype);
  36         64  
  36         1918  
26 36     36   183 use RDF::Trine::Iterator qw(sgrep smap swatch);
  36         83  
  36         2657  
27              
28             ######################################################################
29              
30             our ($VERSION);
31             BEGIN {
32 36     36   48034 $VERSION = '2.915_01';
33             }
34              
35             ######################################################################
36              
37             =head1 METHODS
38              
39             Beyond the methods documented below, this class inherits methods from the
40             L<RDF::Query::Algebra> class.
41              
42             =over 4
43              
44             =cut
45              
46             =item C<new ( $graph, $pattern )>
47              
48             Returns a new NamedGraph structure.
49              
50             =cut
51              
52             sub new {
53 28     28 1 55 my $class = shift;
54 28         52 my $graph = shift;
55 28         51 my $pattern = shift;
56 28         127 return bless( [ 'GRAPH', $graph, $pattern ], $class );
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 69     69 1 106 my $self = shift;
68 69         168 return ($self->graph, $self->pattern);
69             }
70              
71             =item C<< graph >>
72              
73             Returns the graph node of the named graph expression.
74              
75             =cut
76              
77             sub graph {
78 180     180 1 367 my $self = shift;
79 180 50       451 if (@_) {
80 0         0 my $graph = shift;
81 0         0 $self->[1] = $graph;
82             }
83 180         311 my $graph = $self->[1];
84 180         809 return $graph;
85             }
86              
87             =item C<< pattern >>
88              
89             Returns the graph pattern of the named graph expression.
90              
91             =cut
92              
93             sub pattern {
94 144     144 1 809 my $self = shift;
95 144         509 return $self->[2];
96             }
97              
98             =item C<< quads >>
99              
100             Returns a list of the quads belonging to this NamedGraph.
101              
102             =cut
103              
104             sub quads {
105 4     4 1 8 my $self = shift;
106 4         8 my @quads;
107 4         13 foreach my $p ($self->subpatterns_of_type('RDF::Query::Algebra::BasicGraphPattern')) {
108 4         15 push(@quads, $p->quads);
109             }
110 4         8 my @graphquads;
111 4         8 foreach my $q (@quads) {
112 12         36 my $st = RDF::Trine::Statement::Quad->new(
113             $q->subject,
114             $q->predicate,
115             $q->object,
116             $self->graph,
117             );
118 12         218 push(@graphquads, $st);
119             }
120 4         21 return @graphquads;
121             }
122              
123             =item C<< sse >>
124              
125             Returns the SSE string for this algebra expression.
126              
127             =cut
128              
129             sub sse {
130 48     48 1 77 my $self = shift;
131 48         70 my $context = shift;
132 48   100     186 my $prefix = shift || '';
133 48   50     138 my $indent = $context->{indent} || '';
134            
135 48         189 return sprintf(
136             "(namedgraph\n${prefix}${indent}%s\n${prefix}${indent}%s)",
137             $self->graph->sse( $context, "${prefix}${indent}" ),
138             $self->pattern->sse( $context, "${prefix}${indent}" )
139             );
140             }
141              
142             =item C<< explain >>
143              
144             Returns a string serialization of the algebra appropriate for display on the
145             command line.
146              
147             =cut
148              
149             sub explain {
150 0     0 1 0 my $self = shift;
151 0         0 my $s = shift;
152 0         0 my $count = shift;
153 0         0 my $indent = $s x $count;
154 0         0 my $string = "${indent}named graph pattern\n"
155             . "${indent}${s}graph: " . $self->graph->as_string . "\n"
156             . $self->pattern->explain( $s, $count+1 );
157 0         0 return $string;
158             }
159              
160             =item C<< as_sparql >>
161              
162             Returns the SPARQL string for this algebra expression.
163              
164             =cut
165              
166             sub as_sparql {
167 6     6 1 10 my $self = shift;
168 6   50     20 my $context = shift || {};
169 6         11 my $indent = shift;
170 6         26 my $pcontext = { %$context, force_ggp_braces => 1 };
171            
172 6         20 my $string = sprintf(
173             "GRAPH %s %s",
174             $self->graph->as_sparql( $context, $indent ),
175             $self->pattern->as_sparql( $pcontext, $indent ),
176             );
177 6         33 return $string;
178             }
179              
180             =item C<< as_hash >>
181              
182             Returns the query as a nested set of plain data structures (no objects).
183              
184             =cut
185              
186             sub as_hash {
187 0     0 1 0 my $self = shift;
188 0         0 my $context = shift;
189             return {
190 0         0 type => lc($self->type),
191             graph => $self->graph,
192             pattern => $self->pattern->as_hash,
193             };
194             }
195              
196             =item C<< as_spin ( $model ) >>
197              
198             Adds statements to the given model to represent this algebra object in the
199             SPARQL Inferencing Notation (L<http://www.spinrdf.org/>).
200              
201             =cut
202              
203             sub as_spin {
204 0     0 1 0 my $self = shift;
205 0         0 my $model = shift;
206 0         0 my $spin = RDF::Trine::Namespace->new('http://spinrdf.org/spin#');
207 0         0 my $rdf = RDF::Trine::Namespace->new('http://www.w3.org/1999/02/22-rdf-syntax-ns#');
208 0         0 my @t = $self->pattern->as_spin( $model );
209            
210 0         0 my $ng = RDF::Query::Node::Blank->new();
211 0         0 my $list = $model->add_list( @t );
212 0         0 $model->add_statement( RDF::Trine::Statement->new($ng, $rdf->type, $spin->NamedGraph) );
213 0         0 $model->add_statement( RDF::Trine::Statement->new($ng, $spin->elements, $list) );
214            
215 0         0 return $ng;
216             }
217              
218             =item C<< type >>
219              
220             Returns the type of this algebra expression.
221              
222             =cut
223              
224             sub type {
225 0     0 1 0 return 'GRAPH';
226             }
227              
228             =item C<< referenced_variables >>
229              
230             Returns a list of the variable names used in this algebra expression.
231              
232             =cut
233              
234             sub referenced_variables {
235 4     4 1 6 my $self = shift;
236             my @list = RDF::Query::_uniq(
237             $self->pattern->referenced_variables,
238 4         9 (map { $_->name } grep { $_->isa('RDF::Query::Node::Variable') } ($self->graph)),
  4         13  
  4         15  
239             );
240 4         19 return @list;
241             }
242              
243             =item C<< potentially_bound >>
244              
245             Returns a list of the variable names used in this algebra expression that will
246             bind values during execution.
247              
248             =cut
249              
250             sub potentially_bound {
251 3     3 1 7 my $self = shift;
252             my @list = RDF::Query::_uniq(
253             $self->pattern->potentially_bound,
254 3         11 (map { $_->name } grep { $_->isa('RDF::Query::Node::Variable') } ($self->graph)),
  2         8  
  3         17  
255             );
256 3         18 return @list;
257             }
258              
259             =item C<< definite_variables >>
260              
261             Returns a list of the variable names that will be bound after evaluating this algebra expression.
262              
263             =cut
264              
265             sub definite_variables {
266 0     0 1   my $self = shift;
267             return RDF::Query::_uniq(
268             $self->pattern->definite_variables,
269 0           map { $_->name } grep { $_->isa('RDF::Query::Node::Variable') } ($self->graph),
  0            
  0            
270             );
271             }
272              
273              
274             =item C<< qualify_uris ( \%namespaces, $base_uri ) >>
275              
276             Returns a new algebra pattern where all referenced Resource nodes representing
277             QNames (ns:local) are qualified using the supplied %namespaces.
278              
279             =cut
280              
281             sub qualify_uris {
282 0     0 1   my $self = shift;
283 0           my $class = ref($self);
284 0           my $ns = shift;
285 0           my $base_uri = shift;
286            
287 0           my $pattern = $self->pattern->qualify_uris( $ns, $base_uri );
288 0           my $graph = $self->graph;
289 0 0 0       if (blessed($graph) and $graph->isa('RDF::Query::Node::Resource')) {
290 0           my $uri = $graph->uri;
291 0 0         if (ref($uri)) {
292 0           my ($n,$l) = @$uri;
293 0 0         unless (exists($ns->{ $n })) {
294 0           throw RDF::Query::Error::QuerySyntaxError -text => "Namespace $n is not defined";
295             }
296 0           my $resolved = join('', $ns->{ $n }, $l);
297 0           $graph = RDF::Query::Node::Resource->new( $resolved, $base_uri );
298             }
299             }
300 0           return $class->new( $graph, $pattern );
301             }
302              
303             =item C<< check_duplicate_blanks >>
304              
305             Returns true if blank nodes respect the SPARQL rule of no blank-label re-use
306             across BGPs, otherwise throws a RDF::Query::Error::QueryPatternError exception.
307              
308             =cut
309              
310             sub check_duplicate_blanks {
311 0     0 1   my $self = shift;
312 0           my @data;
313 0           foreach my $arg ($self->construct_args) {
314 0 0 0       if (blessed($arg) and $arg->isa('RDF::Query::Algebra')) {
315 0           push(@data, $arg->_referenced_blanks());
316             }
317             }
318            
319 0           my %seen;
320 0           foreach my $d (@data) {
321 0           foreach my $b (@$d) {
322 0 0         if ($seen{ $b }++) {
323 0           throw RDF::Query::Error::QueryPatternError -text => "Same blank node identifier ($b) used in more than one BasicGraphPattern.";
324             }
325             }
326             }
327            
328 0           return 1;
329             }
330              
331             1;
332              
333             __END__
334              
335             =back
336              
337             =head1 AUTHOR
338              
339             Gregory Todd Williams <gwilliams@cpan.org>
340              
341             =cut