File Coverage

blib/lib/RDF/Query/Plan/NamedGraph.pm
Criterion Covered Total %
statement 90 96 93.7
branch 15 24 62.5
condition 1 2 50.0
subroutine 16 16 100.0
pod 11 11 100.0
total 133 149 89.2


line stmt bran cond sub pod time code
1             # RDF::Query::Plan::NamedGraph
2             # -----------------------------------------------------------------------------
3              
4             =head1 NAME
5              
6             RDF::Query::Plan::NamedGraph - Executable query plan for named graphs.
7              
8             =head1 VERSION
9              
10             This document describes RDF::Query::Plan::NamedGraph version 2.915_01.
11              
12             =head1 METHODS
13              
14             Beyond the methods documented below, this class inherits methods from the
15             L<RDF::Query::Plan> class.
16              
17             =over 4
18              
19             =cut
20              
21             package RDF::Query::Plan::NamedGraph;
22              
23 35     35   192 use strict;
  35         75  
  35         904  
24 35     35   192 use warnings;
  35         67  
  35         995  
25 35     35   183 use Scalar::Util qw(blessed);
  35         74  
  35         1696  
26 35     35   186 use base qw(RDF::Query::Plan);
  35         74  
  35         3318  
27              
28             ######################################################################
29              
30             our ($VERSION);
31             BEGIN {
32 35     35   33877 $VERSION = '2.915_01';
33             }
34              
35             ######################################################################
36              
37              
38             =item C<< new ( $graph, $plan ) >>
39              
40             =cut
41              
42             sub new {
43 10     10 1 19 my $class = shift;
44 10         21 my $graph = shift;
45 10         22 my $plan = shift;
46 10         49 my $self = $class->SUPER::new( $graph, $plan );
47 10         71 $self->[0]{referenced_variables} = [ $plan->referenced_variables ];
48            
49 10         48 my $l = Log::Log4perl->get_logger("rdf.query.plan.namedgraph");
50 10         1519 $l->trace('constructing named graph plan...');
51 10         113 return $self;
52             }
53              
54             =item C<< execute ( $execution_context ) >>
55              
56             =cut
57              
58             sub execute ($) {
59 11     11 1 18 my $self = shift;
60 11         21 my $context = shift;
61 11         36 $self->[0]{delegate} = $context->delegate;
62 11 50       45 if ($self->state == $self->OPEN) {
63 0         0 throw RDF::Query::Error::ExecutionError -text => "NamedGraph plan can't be executed while already open";
64             }
65            
66 11         50 my $l = Log::Log4perl->get_logger("rdf.query.plan.namedgraph");
67 11         240 $l->trace('executing named graph plan');
68 11         90 my $model = $context->model;
69 11         57 my $graphs = $model->get_graphs;
70 11         1210 $self->[0]{graphs} = $graphs;
71 11   50     69 $self->[0]{bound} = $context->bound || {};
72 11         30 $self->[0]{context} = $context;
73            
74 11 50       57 if (my $g = $self->[0]{graphs}->next) {
75 11         96 my %bound = %{ $self->[0]{bound} };
  11         34  
76 11         50 $bound{ $self->graph->name } = $g;
77 11         96 my $ctx = $context->copy( bound => \%bound );
78 11         38 my $plan = $self->pattern;
79 11         40 $l->trace("Executing named graph pattern with graph " . $g->as_string . ": " . $plan->sse);
80 11         122 $plan->execute( $ctx );
81 11         83 $self->[0]{current_graph} = $g;
82             }
83            
84 11         60 $self->state( $self->OPEN );
85 11         41 $self;
86             }
87              
88             =item C<< next >>
89              
90             =cut
91              
92             sub next {
93 30     30 1 53 my $self = shift;
94 30 50       98 unless ($self->state == $self->OPEN) {
95 0         0 throw RDF::Query::Error::ExecutionError -text => "next() cannot be called on an un-open NAMED GRAPH";
96             }
97 30         64 my $context = $self->[0]{context};
98            
99 30         99 my $l = Log::Log4perl->get_logger("rdf.query.plan.namedgraph");
100 30         559 while (1) {
101 37 50       166 unless ($self->[0]{current_graph}) {
102 0         0 return;
103             }
104 37         364 my $row = $self->pattern->next;
105 37 100       135 if ($row) {
106 20         43 my $g = $self->[0]{current_graph};
107 20 100       66 if (my $rg = $row->{ $self->graph->name }) {
108 18 50       190 unless ($rg->equal( $g )) {
109 0         0 next;
110             }
111             }
112 20         207 $row->{ $self->graph->name } = $g;
113 20 50       134 if (my $d = $self->delegate) {
114 0         0 $d->log_result( $self, $row );
115             }
116 20         79 return $row;
117             } else {
118 17         79 my $g = $self->[0]{graphs}->next;
119 17 100       310 unless (blessed($g)) {
120 10         38 return;
121             }
122 7         16 my %bound = %{ $self->[0]{bound} };
  7         31  
123 7         25 $bound{ $self->graph->name } = $g;
124 7         62 my $ctx = $self->[0]{context}->copy( bound => \%bound );
125 7         21 my $plan = $self->pattern;
126 7 50       25 if ($plan->state == $plan->OPEN) {
127 7         29 $plan->close();
128             }
129 7         31 $l->trace("Executing named graph pattern with graph " . $g->as_string);
130 7         120 $plan->execute( $ctx );
131 7         44 $self->[0]{current_graph} = $g;
132             }
133             }
134             }
135              
136             =item C<< close >>
137              
138             =cut
139              
140             sub close {
141 11     11 1 27 my $self = shift;
142 11 50       42 unless ($self->state == $self->OPEN) {
143 0         0 throw RDF::Query::Error::ExecutionError -text => "close() cannot be called on an un-open NAMED GRAPH";
144             }
145 11         25 delete $self->[0]{current_graph};
146 11         32 my $plan = $self->pattern;
147 11 50       40 if ($plan->state == $plan->OPEN) {
148 11         41 $plan->close();
149             }
150 11         54 $self->SUPER::close();
151             }
152              
153             =item C<< graph >>
154              
155             Returns the graph variable.
156              
157             =cut
158              
159             sub graph {
160 62     62 1 78 my $self = shift;
161 62         223 return $self->[1];
162             }
163              
164             =item C<< pattern >>
165              
166             Returns the query plan that will be used with each named graph in the model.
167              
168             =cut
169              
170             sub pattern {
171 77     77 1 106 my $self = shift;
172 77         244 return $self->[2];
173             }
174              
175             =item C<< distinct >>
176              
177             Returns true if the pattern is guaranteed to return distinct results.
178              
179             =cut
180              
181             sub distinct {
182 7     7 1 13 my $self = shift;
183 7         20 return $self->pattern->distinct;
184             }
185              
186             =item C<< ordered >>
187              
188             Returns true if the pattern is guaranteed to return ordered results.
189              
190             =cut
191              
192             sub ordered {
193 8     8 1 19 my $self = shift;
194 8         86 return [];
195             }
196              
197             =item C<< plan_node_name >>
198              
199             Returns the string name of this plan node, suitable for use in serialization.
200              
201             =cut
202              
203             sub plan_node_name {
204 2     2 1 9 return 'named-graph';
205             }
206              
207             =item C<< plan_prototype >>
208              
209             Returns a list of scalar identifiers for the type of the content (children)
210             nodes of this plan node. See L<RDF::Query::Plan> for a list of the allowable
211             identifiers.
212              
213             =cut
214              
215             sub plan_prototype {
216 2     2 1 3 my $self = shift;
217 2         10 return qw(N P);
218             }
219              
220             =item C<< plan_node_data >>
221              
222             Returns the data for this plan node that corresponds to the values described by
223             the signature returned by C<< plan_prototype >>.
224              
225             =cut
226              
227             sub plan_node_data {
228 4     4 1 7 my $self = shift;
229 4         13 return ($self->graph, $self->pattern);
230             }
231              
232              
233             1;
234              
235             __END__
236              
237             =back
238              
239             =head1 AUTHOR
240              
241             Gregory Todd Williams <gwilliams@cpan.org>
242              
243             =cut