line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
# RDF::Query::Algebra::Quad |
2
|
|
|
|
|
|
|
# ----------------------------------------------------------------------------- |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
=head1 NAME |
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
RDF::Query::Algebra::Quad - Algebra class for Quad patterns |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
=head1 VERSION |
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
This document describes RDF::Query::Algebra::Quad version 2.915_01. |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
=cut |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
package RDF::Query::Algebra::Quad; |
15
|
|
|
|
|
|
|
|
16
|
36
|
|
|
36
|
|
179
|
use strict; |
|
36
|
|
|
|
|
62
|
|
|
36
|
|
|
|
|
884
|
|
17
|
36
|
|
|
36
|
|
177
|
use warnings; |
|
36
|
|
|
|
|
64
|
|
|
36
|
|
|
|
|
926
|
|
18
|
36
|
|
|
36
|
|
170
|
no warnings 'redefine'; |
|
36
|
|
|
|
|
63
|
|
|
36
|
|
|
|
|
1182
|
|
19
|
36
|
|
|
36
|
|
178
|
use base qw(RDF::Query::Algebra RDF::Trine::Statement::Quad); |
|
36
|
|
|
|
|
60
|
|
|
36
|
|
|
|
|
3715
|
|
20
|
|
|
|
|
|
|
|
21
|
36
|
|
|
36
|
|
181
|
use Data::Dumper; |
|
36
|
|
|
|
|
92
|
|
|
36
|
|
|
|
|
1744
|
|
22
|
36
|
|
|
36
|
|
187
|
use Carp qw(carp croak confess); |
|
36
|
|
|
|
|
72
|
|
|
36
|
|
|
|
|
2032
|
|
23
|
36
|
|
|
36
|
|
173
|
use Scalar::Util qw(blessed reftype refaddr); |
|
36
|
|
|
|
|
66
|
|
|
36
|
|
|
|
|
2057
|
|
24
|
36
|
|
|
36
|
|
181
|
use RDF::Trine::Iterator qw(smap sgrep swatch); |
|
36
|
|
|
|
|
58
|
|
|
36
|
|
|
|
|
2726
|
|
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
###################################################################### |
27
|
|
|
|
|
|
|
|
28
|
|
|
|
|
|
|
my %QUAD_LABELS; |
29
|
|
|
|
|
|
|
our ($VERSION); |
30
|
|
|
|
|
|
|
BEGIN { |
31
|
36
|
|
|
36
|
|
40182
|
$VERSION = '2.915_01'; |
32
|
|
|
|
|
|
|
} |
33
|
|
|
|
|
|
|
|
34
|
|
|
|
|
|
|
###################################################################### |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
=head1 METHODS |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
Beyond the methods documented below, this class inherits methods from the |
39
|
|
|
|
|
|
|
L<RDF::Query::Algebra> class. |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
=over 4 |
42
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
=cut |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
=item C<new ( $s, $p, $o, $g )> |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
Returns a new Quad structure. |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=cut |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
sub new { |
52
|
426
|
|
|
426
|
1
|
1023
|
my $class = shift; |
53
|
426
|
|
|
|
|
910
|
my @nodes = @_; |
54
|
426
|
50
|
|
|
|
1071
|
unless (scalar(@nodes) == 4) { |
55
|
0
|
|
|
|
|
0
|
throw RDF::Query::Error::MethodInvocationError -text => "Quad constructor must have four node arguments"; |
56
|
|
|
|
|
|
|
} |
57
|
426
|
|
|
|
|
1103
|
my @names = qw(subject predicate object context); |
58
|
426
|
|
|
|
|
852
|
foreach my $i (0 .. 3) { |
59
|
1704
|
50
|
33
|
|
|
9070
|
unless (defined($nodes[ $i ]) and blessed($nodes[ $i ])) { |
60
|
0
|
|
|
|
|
0
|
$nodes[ $i ] = RDF::Query::Node::Variable->new($names[ $i ]); |
61
|
|
|
|
|
|
|
} |
62
|
1704
|
100
|
|
|
|
6704
|
unless ($nodes[ $i ]->isa('RDF::Query::Node')) { |
63
|
358
|
|
|
|
|
1390
|
$nodes[ $i ] = RDF::Query::Node->from_trine( $nodes[ $i ] ); |
64
|
|
|
|
|
|
|
} |
65
|
|
|
|
|
|
|
} |
66
|
|
|
|
|
|
|
|
67
|
426
|
|
|
|
|
1863
|
return $class->SUPER::new( @nodes ); |
68
|
|
|
|
|
|
|
} |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=item C<< as_sparql >> |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
Returns the SPARQL string for this algebra expression. |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
=cut |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
sub as_sparql { |
77
|
110
|
|
|
110
|
1
|
175
|
my $self = shift; |
78
|
110
|
|
100
|
|
|
498
|
my $context = shift || {}; |
79
|
110
|
|
|
|
|
188
|
my $indent = shift; |
80
|
|
|
|
|
|
|
|
81
|
110
|
|
|
|
|
321
|
my $pred = $self->predicate; |
82
|
110
|
100
|
100
|
|
|
1037
|
if ($pred->isa('RDF::Trine::Node::Resource') and $pred->uri_value eq 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type') { |
83
|
8
|
|
|
|
|
65
|
$pred = 'a'; |
84
|
|
|
|
|
|
|
} else { |
85
|
102
|
|
|
|
|
901
|
$pred = $pred->as_sparql( $context ); |
86
|
|
|
|
|
|
|
} |
87
|
|
|
|
|
|
|
|
88
|
110
|
|
|
|
|
532
|
my $string = sprintf( |
89
|
|
|
|
|
|
|
"%s %s %s .", |
90
|
|
|
|
|
|
|
$self->subject->as_sparql( $context ), |
91
|
|
|
|
|
|
|
$pred, |
92
|
|
|
|
|
|
|
$self->object->as_sparql( $context ), |
93
|
|
|
|
|
|
|
); |
94
|
110
|
|
|
|
|
2041
|
return $string; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=item C<< as_hash >> |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
Returns the query as a nested set of plain data structures (no objects). |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=cut |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub as_hash { |
104
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
105
|
0
|
|
|
|
|
0
|
my $context = shift; |
106
|
|
|
|
|
|
|
return { |
107
|
|
|
|
|
|
|
type => lc($self->type), |
108
|
0
|
|
|
|
|
0
|
nodes => [ map { $_->as_hash } $self->nodes ], |
|
0
|
|
|
|
|
0
|
|
109
|
|
|
|
|
|
|
}; |
110
|
|
|
|
|
|
|
} |
111
|
|
|
|
|
|
|
|
112
|
|
|
|
|
|
|
=item C<< referenced_blanks >> |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
Returns a list of the blank node names used in this algebra expression. |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
=cut |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
sub referenced_blanks { |
119
|
10
|
|
|
10
|
1
|
16
|
my $self = shift; |
120
|
10
|
|
|
|
|
49
|
my @nodes = $self->nodes; |
121
|
10
|
|
|
|
|
68
|
my @blanks = grep { $_->isa('RDF::Trine::Node::Blank') } @nodes; |
|
40
|
|
|
|
|
159
|
|
122
|
10
|
|
|
|
|
36
|
return map { $_->blank_identifier } @blanks; |
|
0
|
|
|
|
|
0
|
|
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=item C<< qualify_uris ( \%namespaces, $base_uri ) >> |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
Returns a new algebra pattern where all referenced Resource nodes representing |
128
|
|
|
|
|
|
|
QNames (ns:local) are qualified using the supplied %namespaces. |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
=cut |
131
|
|
|
|
|
|
|
|
132
|
|
|
|
|
|
|
sub qualify_uris { |
133
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
134
|
0
|
|
|
|
|
0
|
my $class = ref($self); |
135
|
0
|
|
|
|
|
0
|
my $ns = shift; |
136
|
0
|
|
|
|
|
0
|
my $base_uri = shift; |
137
|
0
|
|
|
|
|
0
|
my @nodes; |
138
|
0
|
|
|
|
|
0
|
foreach my $n ($self->nodes) { |
139
|
0
|
|
|
|
|
0
|
my $blessed = blessed($n); |
140
|
0
|
0
|
0
|
|
|
0
|
if ($blessed and $n->isa('RDF::Query::Node::Resource')) { |
|
|
0
|
0
|
|
|
|
|
141
|
0
|
|
|
|
|
0
|
my $uri = $n->uri; |
142
|
0
|
0
|
|
|
|
0
|
if (ref($uri)) { |
143
|
0
|
|
|
|
|
0
|
my ($n,$l) = @$uri; |
144
|
0
|
0
|
|
|
|
0
|
unless (exists($ns->{ $n })) { |
145
|
0
|
|
|
|
|
0
|
throw RDF::Query::Error::QuerySyntaxError -text => "Namespace $n is not defined"; |
146
|
|
|
|
|
|
|
} |
147
|
0
|
|
|
|
|
0
|
my $resolved = RDF::Query::Node::Resource->new( join('', $ns->{ $n }, $l), $base_uri ); |
148
|
0
|
|
|
|
|
0
|
push(@nodes, $resolved); |
149
|
|
|
|
|
|
|
} else { |
150
|
0
|
|
|
|
|
0
|
push(@nodes, $n); |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
} elsif ($blessed and $n->isa('RDF::Query::Node::Literal')) { |
153
|
0
|
|
|
|
|
0
|
my $node = $n; |
154
|
0
|
|
|
|
|
0
|
my $dt = $node->literal_datatype; |
155
|
0
|
0
|
|
|
|
0
|
if (ref($dt)) { |
156
|
0
|
|
|
|
|
0
|
my ($n,$l) = @$dt; |
157
|
0
|
0
|
|
|
|
0
|
unless (exists($ns->{ $n })) { |
158
|
0
|
|
|
|
|
0
|
throw RDF::Query::Error::QuerySyntaxError -text => "Namespace $n is not defined"; |
159
|
|
|
|
|
|
|
} |
160
|
0
|
|
|
|
|
0
|
my $resolved = RDF::Query::Node::Resource->new( join('', $ns->{ $n }, $l), $base_uri ); |
161
|
0
|
|
|
|
|
0
|
my $lit = RDF::Query::Node::Literal->new( $node->literal_value, undef, $resolved->uri_value ); |
162
|
0
|
|
|
|
|
0
|
push(@nodes, $lit); |
163
|
|
|
|
|
|
|
} else { |
164
|
0
|
|
|
|
|
0
|
push(@nodes, $node); |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
} else { |
167
|
0
|
|
|
|
|
0
|
push(@nodes, $n); |
168
|
|
|
|
|
|
|
} |
169
|
|
|
|
|
|
|
} |
170
|
0
|
|
|
|
|
0
|
return $class->new( @nodes ); |
171
|
|
|
|
|
|
|
} |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
=item C<< bf () >> |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
Returns a string representing the state of the nodes of the triple (bound or free). |
176
|
|
|
|
|
|
|
|
177
|
|
|
|
|
|
|
=cut |
178
|
|
|
|
|
|
|
|
179
|
|
|
|
|
|
|
sub bf { |
180
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
181
|
0
|
|
|
|
|
0
|
my $bf = ''; |
182
|
0
|
|
|
|
|
0
|
foreach my $n ($self->nodes) { |
183
|
0
|
0
|
|
|
|
0
|
$bf .= ($n->isa('RDF::Query::Node::Variable')) |
184
|
|
|
|
|
|
|
? 'f' |
185
|
|
|
|
|
|
|
: 'b'; |
186
|
|
|
|
|
|
|
} |
187
|
0
|
|
|
|
|
0
|
return $bf; |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
=item C<< distinguish_bnode_variables >> |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
Returns a new Quad object with blank nodes replaced by distinguished variables. |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
=cut |
195
|
|
|
|
|
|
|
|
196
|
|
|
|
|
|
|
sub distinguish_bnode_variables { |
197
|
80
|
|
|
80
|
1
|
133
|
my $self = shift; |
198
|
80
|
|
|
|
|
165
|
my $class = ref($self); |
199
|
80
|
|
|
|
|
250
|
my @nodes = $self->nodes; |
200
|
80
|
|
|
|
|
517
|
foreach my $i (0 .. $#nodes) { |
201
|
320
|
50
|
|
|
|
1521
|
if ($nodes[$i]->isa('RDF::Query::Node::Blank')) { |
202
|
0
|
|
|
|
|
0
|
$nodes[$i] = $nodes[$i]->make_distinguished_variable; |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
} |
205
|
80
|
|
|
|
|
291
|
return $class->new( @nodes ); |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
=item C<< label ( $label => $value ) >> |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
Sets the named C<< $label >> to C<< $value >> for this quad object. |
211
|
|
|
|
|
|
|
If no C<< $value >> is given, returns the current label value, or undef if none |
212
|
|
|
|
|
|
|
exists. |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=cut |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
sub label { |
217
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
218
|
0
|
|
|
|
|
0
|
my $addr = refaddr($self); |
219
|
0
|
|
|
|
|
0
|
my $label = shift; |
220
|
0
|
0
|
|
|
|
0
|
if (@_) { |
221
|
0
|
|
|
|
|
0
|
my $value = shift; |
222
|
0
|
|
|
|
|
0
|
$QUAD_LABELS{ $addr }{ $label } = $value; |
223
|
|
|
|
|
|
|
} |
224
|
0
|
0
|
|
|
|
0
|
if (exists $QUAD_LABELS{ $addr }) { |
225
|
0
|
|
|
|
|
0
|
return $QUAD_LABELS{ $addr }{ $label }; |
226
|
|
|
|
|
|
|
} else { |
227
|
0
|
|
|
|
|
0
|
return; |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
sub DESTROY { |
232
|
426
|
|
|
426
|
|
650
|
my $self = shift; |
233
|
426
|
|
|
|
|
995
|
my $addr = refaddr( $self ); |
234
|
426
|
|
|
|
|
1790
|
delete $QUAD_LABELS{ $addr }; |
235
|
|
|
|
|
|
|
} |
236
|
|
|
|
|
|
|
|
237
|
|
|
|
|
|
|
|
238
|
|
|
|
|
|
|
1; |
239
|
|
|
|
|
|
|
|
240
|
|
|
|
|
|
|
__END__ |
241
|
|
|
|
|
|
|
|
242
|
|
|
|
|
|
|
=back |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
=head1 AUTHOR |
245
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
Gregory Todd Williams <gwilliams@cpan.org> |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
=cut |