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.916.
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   191 use strict;
  35         79  
  35         946  
24 35     35   190 use warnings;
  35         77  
  35         1074  
25 35     35   194 use Scalar::Util qw(blessed);
  35         76  
  35         2003  
26 35     35   189 use base qw(RDF::Query::Plan);
  35         80  
  35         3545  
27              
28             ######################################################################
29              
30             our ($VERSION);
31             BEGIN {
32 35     35   35017 $VERSION = '2.916';
33             }
34              
35             ######################################################################
36              
37              
38             =item C<< new ( $graph, $plan ) >>
39              
40             =cut
41              
42             sub new {
43 10     10 1 21 my $class = shift;
44 10         17 my $graph = shift;
45 10         21 my $plan = shift;
46 10         50 my $self = $class->SUPER::new( $graph, $plan );
47 10         58 $self->[0]{referenced_variables} = [ $plan->referenced_variables ];
48            
49 10         49 my $l = Log::Log4perl->get_logger("rdf.query.plan.namedgraph");
50 10         1535 $l->trace('constructing named graph plan...');
51 10         116 return $self;
52             }
53              
54             =item C<< execute ( $execution_context ) >>
55              
56             =cut
57              
58             sub execute ($) {
59 11     11 1 25 my $self = shift;
60 11         19 my $context = shift;
61 11         39 $self->[0]{delegate} = $context->delegate;
62 11 50       51 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         51 my $l = Log::Log4perl->get_logger("rdf.query.plan.namedgraph");
67 11         357 $l->trace('executing named graph plan');
68 11         91 my $model = $context->model;
69 11         92 my $graphs = $model->get_graphs;
70 11         1203 $self->[0]{graphs} = $graphs;
71 11   50     47 $self->[0]{bound} = $context->bound || {};
72 11         31 $self->[0]{context} = $context;
73            
74 11 50       60 if (my $g = $self->[0]{graphs}->next) {
75 11         94 my %bound = %{ $self->[0]{bound} };
  11         38  
76 11         55 $bound{ $self->graph->name } = $g;
77 11         98 my $ctx = $context->copy( bound => \%bound );
78 11         37 my $plan = $self->pattern;
79 11         50 $l->trace("Executing named graph pattern with graph " . $g->as_string . ": " . $plan->sse);
80 11         129 $plan->execute( $ctx );
81 11         85 $self->[0]{current_graph} = $g;
82             }
83            
84 11         63 $self->state( $self->OPEN );
85 11         38 $self;
86             }
87              
88             =item C<< next >>
89              
90             =cut
91              
92             sub next {
93 30     30 1 46 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         82 my $context = $self->[0]{context};
98            
99 30         96 my $l = Log::Log4perl->get_logger("rdf.query.plan.namedgraph");
100 30         557 while (1) {
101 37 50       161 unless ($self->[0]{current_graph}) {
102 0         0 return;
103             }
104 37         361 my $row = $self->pattern->next;
105 37 100       119 if ($row) {
106 20         39 my $g = $self->[0]{current_graph};
107 20 100       66 if (my $rg = $row->{ $self->graph->name }) {
108 18 50       191 unless ($rg->equal( $g )) {
109 0         0 next;
110             }
111             }
112 20         207 $row->{ $self->graph->name } = $g;
113 20 50       145 if (my $d = $self->delegate) {
114 0         0 $d->log_result( $self, $row );
115             }
116 20         79 return $row;
117             } else {
118 17         78 my $g = $self->[0]{graphs}->next;
119 17 100       301 unless (blessed($g)) {
120 10         36 return;
121             }
122 7         19 my %bound = %{ $self->[0]{bound} };
  7         29  
123 7         26 $bound{ $self->graph->name } = $g;
124 7         61 my $ctx = $self->[0]{context}->copy( bound => \%bound );
125 7         24 my $plan = $self->pattern;
126 7 50       28 if ($plan->state == $plan->OPEN) {
127 7         33 $plan->close();
128             }
129 7         31 $l->trace("Executing named graph pattern with graph " . $g->as_string);
130 7         124 $plan->execute( $ctx );
131 7         43 $self->[0]{current_graph} = $g;
132             }
133             }
134             }
135              
136             =item C<< close >>
137              
138             =cut
139              
140             sub close {
141 11     11 1 22 my $self = shift;
142 11 50       51 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         32 delete $self->[0]{current_graph};
146 11         32 my $plan = $self->pattern;
147 11 50       39 if ($plan->state == $plan->OPEN) {
148 11         48 $plan->close();
149             }
150 11         60 $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 85 my $self = shift;
161 62         233 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 108 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 14 my $self = shift;
183 7         21 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 15 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 23 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         13 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         15 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