line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
=encoding utf8 |
2
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
=head1 NAME |
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
RDF::Trine::Store::LanguagePreference - RDF Store proxy for filtering language tagged literals |
6
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
=head1 VERSION |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
This document describes RDF::Trine::Store::LanguagePreference version 1.017 |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
=head1 SYNOPSIS |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
use RDF::Trine::Store::LanguagePreference; |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
=head1 DESCRIPTION |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
RDF::Trine::Store::LanguagePreference provides a RDF::Trine::Store API to |
18
|
|
|
|
|
|
|
filter the statements made available from some underlying store object based |
19
|
|
|
|
|
|
|
on a users' language preferences (e.g. coming from an Accept-Language HTTP |
20
|
|
|
|
|
|
|
header value). |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
=cut |
23
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
package RDF::Trine::Store::LanguagePreference; |
25
|
|
|
|
|
|
|
|
26
|
68
|
|
|
68
|
|
452
|
use strict; |
|
68
|
|
|
|
|
177
|
|
|
68
|
|
|
|
|
1927
|
|
27
|
68
|
|
|
68
|
|
346
|
use warnings; |
|
68
|
|
|
|
|
200
|
|
|
68
|
|
|
|
|
1817
|
|
28
|
68
|
|
|
68
|
|
361
|
no warnings 'redefine'; |
|
68
|
|
|
|
|
149
|
|
|
68
|
|
|
|
|
2008
|
|
29
|
68
|
|
|
68
|
|
379
|
use base qw(RDF::Trine::Store); |
|
68
|
|
|
|
|
161
|
|
|
68
|
|
|
|
|
4716
|
|
30
|
|
|
|
|
|
|
|
31
|
68
|
|
|
68
|
|
428
|
use Data::Dumper; |
|
68
|
|
|
|
|
168
|
|
|
68
|
|
|
|
|
3224
|
|
32
|
68
|
|
|
68
|
|
392
|
use List::Util qw(reduce max); |
|
68
|
|
|
|
|
186
|
|
|
68
|
|
|
|
|
3763
|
|
33
|
68
|
|
|
68
|
|
428
|
use Scalar::Util qw(refaddr reftype blessed); |
|
68
|
|
|
|
|
166
|
|
|
68
|
|
|
|
|
3322
|
|
34
|
68
|
|
|
68
|
|
416
|
use RDF::Trine::Iterator qw(sgrep); |
|
68
|
|
|
|
|
165
|
|
|
68
|
|
|
|
|
5394
|
|
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
###################################################################### |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
my @pos_names; |
39
|
|
|
|
|
|
|
our $VERSION; |
40
|
|
|
|
|
|
|
BEGIN { |
41
|
68
|
|
|
68
|
|
265
|
$VERSION = "1.017"; |
42
|
68
|
|
|
|
|
170
|
my $class = __PACKAGE__; |
43
|
68
|
|
|
|
|
182
|
$RDF::Trine::Store::STORE_CLASSES{ $class } = $VERSION; |
44
|
68
|
|
|
|
|
73742
|
@pos_names = qw(subject predicate object context); |
45
|
|
|
|
|
|
|
} |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
###################################################################### |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
=head1 METHODS |
50
|
|
|
|
|
|
|
|
51
|
|
|
|
|
|
|
Beyond the methods documented below, this class inherits methods from the |
52
|
|
|
|
|
|
|
L<RDF::Trine::Store> class. |
53
|
|
|
|
|
|
|
|
54
|
|
|
|
|
|
|
=over 4 |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
=item C<< new ( $store, { $lang1 => $q1, $lang2 => $q2, ... } ) >> |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
Returns a new storage object that will act as a proxy for the C<< $store >> object, |
59
|
|
|
|
|
|
|
filtering language literals based on the expressed language preferences. |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
=item C<new_with_config ( $hashref )> |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
Returns a new storage object configured with a hashref with certain |
64
|
|
|
|
|
|
|
keys as arguments. |
65
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
|
The C<storetype> key must be C<LanguagePreference> for this backend. |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
The following key must also be used: |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
=over |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
=item C<store> |
73
|
|
|
|
|
|
|
|
74
|
|
|
|
|
|
|
A configuration hash for the underlying store object. |
75
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
=item C<preferred_languages> |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
A hash reference mapping language tags to quality values in the range [0, 1]. |
79
|
|
|
|
|
|
|
The referent may be changed between operations to change the set of preferred |
80
|
|
|
|
|
|
|
languages used in statement matching. |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
=back |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
=cut |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
sub new { |
87
|
3
|
|
|
3
|
1
|
1614
|
my $class = shift; |
88
|
3
|
|
|
|
|
8
|
my $store = shift; |
89
|
3
|
|
|
|
|
7
|
my $pref = shift; |
90
|
3
|
|
|
|
|
14
|
my $self = bless({ |
91
|
|
|
|
|
|
|
store => $store, |
92
|
|
|
|
|
|
|
preferred_languages => $pref, |
93
|
|
|
|
|
|
|
}, $class); |
94
|
3
|
|
|
|
|
10
|
return $self; |
95
|
|
|
|
|
|
|
} |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=item C<< new_with_config ( \%config ) >> |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
Returns a new RDF::Trine::Store object based on the supplied configuration hashref. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=cut |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
sub new_with_config { |
104
|
0
|
|
|
0
|
1
|
0
|
my $proto = shift; |
105
|
0
|
|
|
|
|
0
|
my $config = shift; |
106
|
0
|
|
|
|
|
0
|
$config->{storetype} = 'LanguagePreference'; |
107
|
0
|
|
|
|
|
0
|
return $proto->SUPER::new_with_config( $config ); |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
sub _new_with_config { |
111
|
0
|
|
|
0
|
|
0
|
my $class = shift; |
112
|
0
|
|
|
|
|
0
|
my $config = shift; |
113
|
0
|
|
|
|
|
0
|
return $class->new( @{ $config }{ qw(store preferred_languages) } ); |
|
0
|
|
|
|
|
0
|
|
114
|
|
|
|
|
|
|
} |
115
|
|
|
|
|
|
|
|
116
|
|
|
|
|
|
|
sub _config_meta { |
117
|
|
|
|
|
|
|
return { |
118
|
0
|
|
|
0
|
|
0
|
required_keys => [qw(store preferred_languages)], |
119
|
|
|
|
|
|
|
fields => { |
120
|
|
|
|
|
|
|
store => { description => 'Store config', type => 'string' }, |
121
|
|
|
|
|
|
|
preferred_languages => { description => 'Preferred languages', type => 'hash' }, |
122
|
|
|
|
|
|
|
} |
123
|
|
|
|
|
|
|
} |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
=item C<< language_preferences >> |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
Returns a hash of the language preference quality values. |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=cut |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
sub language_preferences { |
134
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
135
|
0
|
|
|
|
|
0
|
return %{ $self->{preferred_languages} }; |
|
0
|
|
|
|
|
0
|
|
136
|
|
|
|
|
|
|
} |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
=item C<< language_preference( $lang ) >> |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
Return the quality value preference for the given language. |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
=cut |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
sub language_preference { |
145
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
146
|
0
|
|
|
|
|
0
|
my $lang = shift; |
147
|
0
|
|
|
|
|
0
|
return $self->{preferred_languages}{$lang}; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
=item C<< update_language_preference( $lang => $qvalue ) >> |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
Update the quality value preference for the given language. |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
=cut |
155
|
|
|
|
|
|
|
|
156
|
|
|
|
|
|
|
sub update_language_preference { |
157
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
158
|
0
|
|
|
|
|
0
|
my $lang = shift; |
159
|
0
|
|
|
|
|
0
|
my $q = shift; |
160
|
0
|
0
|
|
|
|
0
|
if ($q == 0) { |
161
|
0
|
|
|
|
|
0
|
delete $self->{preferred_languages}{$lang}; |
162
|
|
|
|
|
|
|
} else { |
163
|
0
|
|
|
|
|
0
|
$self->{preferred_languages}{$lang} = $q; |
164
|
|
|
|
|
|
|
} |
165
|
|
|
|
|
|
|
} |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
=item C<< get_statements ( $subject, $predicate, $object [, $context] ) >> |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
Returns a stream object of all statements matching the specified subject, |
170
|
|
|
|
|
|
|
predicate and objects. Any of the arguments may be undef to match any value. |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
=cut |
173
|
|
|
|
|
|
|
|
174
|
|
|
|
|
|
|
sub get_statements { |
175
|
4
|
|
|
4
|
1
|
10
|
my $self = shift; |
176
|
4
|
|
|
|
|
17
|
my @nodes = @_[0..3]; |
177
|
4
|
|
|
|
|
9
|
my $bound = 0; |
178
|
4
|
|
|
|
|
8
|
my %bound; |
179
|
|
|
|
|
|
|
|
180
|
4
|
|
|
|
|
9
|
my $use_quad = 0; |
181
|
4
|
100
|
|
|
|
15
|
if (scalar(@_) >= 4) { |
182
|
1
|
|
|
|
|
3
|
my $g = $nodes[3]; |
183
|
1
|
0
|
33
|
|
|
7
|
if (blessed($g) and not($g->is_variable) and not($g->is_nil)) { |
|
|
|
33
|
|
|
|
|
184
|
0
|
|
|
|
|
0
|
$use_quad = 1; |
185
|
0
|
|
|
|
|
0
|
$bound++; |
186
|
0
|
|
|
|
|
0
|
$bound{ 3 } = $g; |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
4
|
|
|
|
|
13
|
my @var_map = qw(s p o g); |
191
|
4
|
|
|
|
|
16
|
my %var_map = map { $var_map[$_] => $_ } (0 .. $#var_map); |
|
16
|
|
|
|
|
45
|
|
192
|
4
|
|
|
|
|
10
|
my @node_map; |
193
|
4
|
|
|
|
|
19
|
foreach my $i (0 .. $#nodes) { |
194
|
16
|
100
|
66
|
|
|
62
|
if (not(blessed($nodes[$i])) or $nodes[$i]->is_variable) { |
195
|
13
|
|
|
|
|
50
|
$nodes[$i] = RDF::Trine::Node::Variable->new( $var_map[ $i ] ); |
196
|
|
|
|
|
|
|
} |
197
|
|
|
|
|
|
|
} |
198
|
|
|
|
|
|
|
|
199
|
4
|
|
|
|
|
11
|
my $cache = {}; |
200
|
4
|
|
|
|
|
27
|
my $iter = $self->{store}->get_statements(@nodes); |
201
|
|
|
|
|
|
|
return RDF::Trine::Iterator::sgrep(sub { |
202
|
45
|
|
|
45
|
|
105
|
return $self->languagePreferenceAllowsStatement($_, $cache); |
203
|
4
|
|
|
|
|
27
|
}, $iter); |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
|
|
|
|
|
|
=item C<< count_statements ( $subject, $predicate, $object, $context ) >> |
207
|
|
|
|
|
|
|
|
208
|
|
|
|
|
|
|
Returns a count of all the statements matching the specified subject, |
209
|
|
|
|
|
|
|
predicate, object, and context. Any of the arguments may be undef to match any |
210
|
|
|
|
|
|
|
value. |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
=cut |
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
sub count_statements { |
215
|
1
|
|
|
1
|
1
|
3
|
my $self = shift; |
216
|
1
|
|
|
|
|
4
|
my $iter = $self->get_statements(@_); |
217
|
1
|
|
|
|
|
2
|
my $count = 0; |
218
|
1
|
|
|
|
|
7
|
while ($iter->next) { |
219
|
2
|
|
|
|
|
5
|
$count++; |
220
|
|
|
|
|
|
|
} |
221
|
1
|
|
|
|
|
11
|
return $count; |
222
|
|
|
|
|
|
|
} |
223
|
|
|
|
|
|
|
|
224
|
|
|
|
|
|
|
=item C<< qvalueForLanguage ( $language, \%cache ) >> |
225
|
|
|
|
|
|
|
|
226
|
|
|
|
|
|
|
Returns the q-value for C<< $language >> based on the current language |
227
|
|
|
|
|
|
|
preference. C<< %cache >> is used across multiple calls to this method for |
228
|
|
|
|
|
|
|
performance reasons. |
229
|
|
|
|
|
|
|
|
230
|
|
|
|
|
|
|
=cut |
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub qvalueForLanguage { |
233
|
484
|
|
|
484
|
1
|
660
|
my $self = shift; |
234
|
484
|
|
|
|
|
664
|
my $lang = shift; |
235
|
484
|
|
50
|
|
|
992
|
my $cache = shift || {}; |
236
|
484
|
100
|
|
|
|
944
|
if (exists $cache->{$lang}) { |
237
|
440
|
|
|
|
|
1028
|
return $cache->{$lang}; |
238
|
|
|
|
|
|
|
} else { |
239
|
44
|
|
|
|
|
59
|
my %q; |
240
|
44
|
|
|
|
|
64
|
foreach my $l (keys %{ $self->{preferred_languages} }) { |
|
44
|
|
|
|
|
90
|
|
241
|
33
|
100
|
|
|
|
222
|
if ($lang =~ /^$l/) { |
242
|
3
|
|
|
|
|
8
|
my $q = $self->{preferred_languages}{$l}; |
243
|
3
|
|
|
|
|
8
|
$q{$l} = $q; |
244
|
|
|
|
|
|
|
} |
245
|
|
|
|
|
|
|
} |
246
|
44
|
|
|
|
|
73
|
my $q; |
247
|
44
|
100
|
|
|
|
61
|
if (scalar(@{ [ keys %q ] })) { |
|
44
|
|
|
|
|
101
|
|
248
|
3
|
|
|
|
|
12
|
my @keys = sort { length($b) <=> length($a) } keys %q; |
|
0
|
|
|
|
|
0
|
|
249
|
3
|
|
|
|
|
6
|
$q = $q{$keys[0]}; |
250
|
|
|
|
|
|
|
} else { |
251
|
41
|
|
|
|
|
59
|
$q = 0.001; |
252
|
|
|
|
|
|
|
} |
253
|
44
|
|
|
|
|
87
|
$cache->{$lang} = $q; |
254
|
44
|
|
|
|
|
105
|
return $q; |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
} |
257
|
|
|
|
|
|
|
|
258
|
|
|
|
|
|
|
=item C<< siteQValueForLanguage ( $language ) >> |
259
|
|
|
|
|
|
|
|
260
|
|
|
|
|
|
|
Returns an implementation-specific q-value preference for the given |
261
|
|
|
|
|
|
|
C<< $language >>. This method may be overridden by subclasses to control the |
262
|
|
|
|
|
|
|
default preferred language. |
263
|
|
|
|
|
|
|
|
264
|
|
|
|
|
|
|
=cut |
265
|
|
|
|
|
|
|
|
266
|
|
|
|
|
|
|
sub siteQValueForLanguage { |
267
|
484
|
|
|
484
|
1
|
719
|
my $self = shift; |
268
|
484
|
|
|
|
|
684
|
my $lang = shift; |
269
|
484
|
100
|
|
|
|
1487
|
return ($lang =~ /^en/) ? 1.0 : 0.999; |
270
|
|
|
|
|
|
|
} |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
=item C<< availableLanguagesForStatement( $statement ) >> |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
Returns a list of language tags that are available in the underlying store for |
275
|
|
|
|
|
|
|
the given statement object. For example, if C<< $statement >> represented the |
276
|
|
|
|
|
|
|
triple: |
277
|
|
|
|
|
|
|
|
278
|
|
|
|
|
|
|
dbpedia:Los_Angeles rdf:label "Los Angeles"@en |
279
|
|
|
|
|
|
|
|
280
|
|
|
|
|
|
|
and the underlying store contains the triples: |
281
|
|
|
|
|
|
|
|
282
|
|
|
|
|
|
|
dbpedia:Los_Angeles rdf:label "Los Angeles"@en |
283
|
|
|
|
|
|
|
dbpedia:Los_Angeles rdf:label "ããµã³ã¼ã«ã¹"@ja |
284
|
|
|
|
|
|
|
dbpedia:Los_Angeles rdf:label "ÐоÑ-ÐнджелеÑ"@ru |
285
|
|
|
|
|
|
|
|
286
|
|
|
|
|
|
|
then the return value would be C<< ('en', 'ja', 'ru') >>. |
287
|
|
|
|
|
|
|
|
288
|
|
|
|
|
|
|
=cut |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
sub availableLanguagesForStatement { |
291
|
44
|
|
|
44
|
1
|
74
|
my $self = shift; |
292
|
44
|
|
|
|
|
60
|
my $st = shift; |
293
|
44
|
|
|
|
|
68
|
my %languages; |
294
|
44
|
|
|
|
|
124
|
my @nodes = $st->nodes; |
295
|
44
|
|
|
|
|
84
|
$nodes[2] = undef; |
296
|
44
|
|
|
|
|
145
|
my $iter = $self->{store}->get_statements(@nodes); |
297
|
44
|
|
|
|
|
144
|
while (my $q = $iter->next) { |
298
|
484
|
|
|
|
|
1062
|
my $object = $q->object; |
299
|
484
|
50
|
33
|
|
|
1755
|
if ($object->isa('RDF::Trine::Node::Literal') and $object->has_language) { |
300
|
484
|
|
|
|
|
1063
|
my $language = $object->literal_value_language; |
301
|
484
|
|
|
|
|
1410
|
$languages{$language}++; |
302
|
|
|
|
|
|
|
} |
303
|
|
|
|
|
|
|
} |
304
|
44
|
|
|
|
|
478
|
return keys %languages; |
305
|
|
|
|
|
|
|
} |
306
|
|
|
|
|
|
|
|
307
|
|
|
|
|
|
|
=item C<< languagePreferenceAllowsStatement ( $statement, \%cache ) >> |
308
|
|
|
|
|
|
|
|
309
|
|
|
|
|
|
|
Returns true if the C<< $statement >> is allowed by the current language |
310
|
|
|
|
|
|
|
preference. C<< %cache >> is used across multiple calls to this method for |
311
|
|
|
|
|
|
|
performance reasons. |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
=cut |
314
|
|
|
|
|
|
|
|
315
|
|
|
|
|
|
|
sub languagePreferenceAllowsStatement { |
316
|
45
|
|
|
45
|
1
|
76
|
my $self = shift; |
317
|
45
|
|
|
|
|
66
|
my $st = shift; |
318
|
45
|
|
|
|
|
71
|
my $cache = shift; |
319
|
45
|
|
|
|
|
127
|
my $object = $st->object; |
320
|
45
|
100
|
66
|
|
|
224
|
if ($object->isa('RDF::Trine::Node::Literal') and $object->has_language) { |
321
|
44
|
|
|
|
|
105
|
my $language = $object->literal_value_language; |
322
|
44
|
|
|
|
|
103
|
my @availableLanguages = $self->availableLanguagesForStatement($st); |
323
|
44
|
|
|
|
|
122
|
my %availableValues = map { $_ => $self->qvalueForLanguage($_, $cache) * $self->siteQValueForLanguage($_) } @availableLanguages; |
|
484
|
|
|
|
|
938
|
|
324
|
44
|
100
|
|
440
|
|
357
|
my $prefLang = reduce { $availableValues{$a} > $availableValues{$b} ? $a : $b } keys %availableValues; |
|
440
|
|
|
|
|
999
|
|
325
|
44
|
|
|
|
|
278
|
return ($prefLang eq $language); |
326
|
|
|
|
|
|
|
} else { |
327
|
1
|
|
|
|
|
4
|
return 1; |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
} |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
|
332
|
|
|
|
|
|
|
=item C<< supports ( [ $feature ] ) >> |
333
|
|
|
|
|
|
|
|
334
|
|
|
|
|
|
|
If C<< $feature >> is specified, returns true if the feature is supported by the |
335
|
|
|
|
|
|
|
store, false otherwise. If C<< $feature >> is not specified, returns a list of |
336
|
|
|
|
|
|
|
supported features. |
337
|
|
|
|
|
|
|
|
338
|
|
|
|
|
|
|
=cut |
339
|
|
|
|
|
|
|
|
340
|
|
|
|
|
|
|
sub supports { |
341
|
0
|
|
|
0
|
1
|
0
|
my $self = shift; |
342
|
0
|
|
|
|
|
0
|
return; |
343
|
|
|
|
|
|
|
} |
344
|
|
|
|
|
|
|
|
345
|
|
|
|
|
|
|
=begin private |
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
=item C<< can >> |
348
|
|
|
|
|
|
|
|
349
|
|
|
|
|
|
|
Delegating implementation. |
350
|
|
|
|
|
|
|
|
351
|
|
|
|
|
|
|
=end private |
352
|
|
|
|
|
|
|
|
353
|
|
|
|
|
|
|
=cut |
354
|
|
|
|
|
|
|
|
355
|
|
|
|
|
|
|
sub can { |
356
|
2
|
|
|
2
|
1
|
3
|
my $proto = shift; |
357
|
2
|
|
|
|
|
5
|
my $name = shift; |
358
|
2
|
|
|
|
|
6
|
my %methods = map { $_ => 1 } qw(new new_with_config _new_with_config get_statements count_statements); |
|
10
|
|
|
|
|
22
|
|
359
|
2
|
50
|
|
|
|
8
|
return 1 if exists $methods{$name}; |
360
|
2
|
50
|
|
|
|
5
|
if (ref($proto)) { |
361
|
2
|
|
|
|
|
18
|
return $proto->{store}->can($name); |
362
|
|
|
|
|
|
|
} else { |
363
|
0
|
|
|
|
|
|
return; |
364
|
|
|
|
|
|
|
} |
365
|
|
|
|
|
|
|
} |
366
|
|
|
|
|
|
|
|
367
|
|
|
|
|
|
|
sub AUTOLOAD { |
368
|
0
|
|
|
0
|
|
|
my $self = shift; |
369
|
0
|
|
|
|
|
|
our $AUTOLOAD; |
370
|
0
|
0
|
|
|
|
|
return if ($AUTOLOAD =~ /:DESTROY$/); |
371
|
0
|
|
|
|
|
|
my ($name) = ($AUTOLOAD =~ m/^.*:(.*)$/); |
372
|
0
|
|
|
|
|
|
my $store = $self->{store}; |
373
|
0
|
0
|
|
|
|
|
unless ($store->can($name)) { |
374
|
0
|
|
|
|
|
|
my $class = ref($store); |
375
|
0
|
|
|
|
|
|
Carp::confess qq[Can't locate object method "$name" via package "$class"]; |
376
|
|
|
|
|
|
|
} |
377
|
0
|
|
|
|
|
|
return $store->$name(@_); |
378
|
|
|
|
|
|
|
} |
379
|
|
|
|
|
|
|
|
380
|
|
|
|
|
|
|
1; |
381
|
|
|
|
|
|
|
|
382
|
|
|
|
|
|
|
__END__ |
383
|
|
|
|
|
|
|
|
384
|
|
|
|
|
|
|
=back |
385
|
|
|
|
|
|
|
|
386
|
|
|
|
|
|
|
=head1 BUGS |
387
|
|
|
|
|
|
|
|
388
|
|
|
|
|
|
|
Please report any bugs or feature requests to through the GitHub web interface |
389
|
|
|
|
|
|
|
at L<https://github.com/kasei/perlrdf/issues>. |
390
|
|
|
|
|
|
|
|
391
|
|
|
|
|
|
|
=head1 AUTHOR |
392
|
|
|
|
|
|
|
|
393
|
|
|
|
|
|
|
Gregory Todd Williams C<< <gwilliams@cpan.org> >> |
394
|
|
|
|
|
|
|
|
395
|
|
|
|
|
|
|
=head1 COPYRIGHT |
396
|
|
|
|
|
|
|
|
397
|
|
|
|
|
|
|
Copyright (c) 2006-2012 Gregory Todd Williams. This |
398
|
|
|
|
|
|
|
program is free software; you can redistribute it and/or modify it under |
399
|
|
|
|
|
|
|
the same terms as Perl itself. |
400
|
|
|
|
|
|
|
|
401
|
|
|
|
|
|
|
=cut |