rdf 3.0.11 → 3.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/AUTHORS +1 -1
- data/README.md +127 -95
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/etc/doap.nt +79 -85
- data/lib/rdf.rb +35 -23
- data/lib/rdf/changeset.rb +80 -19
- data/lib/rdf/cli.rb +7 -7
- data/lib/rdf/format.rb +17 -10
- data/lib/rdf/mixin/enumerable.rb +4 -3
- data/lib/rdf/mixin/mutable.rb +5 -15
- data/lib/rdf/mixin/queryable.rb +12 -4
- data/lib/rdf/mixin/transactable.rb +2 -2
- data/lib/rdf/mixin/writable.rb +9 -14
- data/lib/rdf/model/dataset.rb +1 -1
- data/lib/rdf/model/graph.rb +7 -4
- data/lib/rdf/model/list.rb +5 -5
- data/lib/rdf/model/literal.rb +3 -3
- data/lib/rdf/model/statement.rb +32 -9
- data/lib/rdf/model/uri.rb +53 -32
- data/lib/rdf/nquads.rb +6 -6
- data/lib/rdf/ntriples.rb +7 -5
- data/lib/rdf/ntriples/reader.rb +29 -7
- data/lib/rdf/ntriples/writer.rb +10 -1
- data/lib/rdf/query.rb +27 -35
- data/lib/rdf/query/hash_pattern_normalizer.rb +14 -12
- data/lib/rdf/query/pattern.rb +51 -18
- data/lib/rdf/query/solution.rb +20 -1
- data/lib/rdf/query/solutions.rb +15 -5
- data/lib/rdf/query/variable.rb +17 -5
- data/lib/rdf/reader.rb +76 -25
- data/lib/rdf/repository.rb +32 -18
- data/lib/rdf/transaction.rb +1 -1
- data/lib/rdf/util.rb +6 -5
- data/lib/rdf/util/cache.rb +2 -2
- data/lib/rdf/util/coercions.rb +60 -0
- data/lib/rdf/util/file.rb +20 -10
- data/lib/rdf/util/logger.rb +6 -6
- data/lib/rdf/util/uuid.rb +4 -4
- data/lib/rdf/vocab/owl.rb +401 -86
- data/lib/rdf/vocab/rdfs.rb +81 -18
- data/lib/rdf/vocab/rdfv.rb +147 -1
- data/lib/rdf/vocab/writer.rb +41 -3
- data/lib/rdf/vocab/xsd.rb +203 -2
- data/lib/rdf/vocabulary.rb +73 -15
- data/lib/rdf/writer.rb +33 -11
- metadata +34 -28
data/lib/rdf/query/solution.rb
CHANGED
@@ -195,12 +195,31 @@ class RDF::Query
|
|
195
195
|
# Merges the bindings from the given `other` query solution into this
|
196
196
|
# one, overwriting any existing ones having the same name.
|
197
197
|
#
|
198
|
+
# ## RDFStar (RDF*)
|
199
|
+
#
|
200
|
+
# If merging a binding for a statement to a pattern,
|
201
|
+
# merge their embedded solutions.
|
202
|
+
#
|
198
203
|
# @param [RDF::Query::Solution, #to_h] other
|
199
204
|
# another query solution or hash bindings
|
200
205
|
# @return [void] self
|
201
206
|
# @since 0.3.0
|
202
207
|
def merge!(other)
|
203
|
-
@bindings.merge!(other.to_h)
|
208
|
+
@bindings.merge!(other.to_h) do |key, v1, v2|
|
209
|
+
# Don't merge a pattern over a statement
|
210
|
+
# This happens because JOIN does a reverse merge,
|
211
|
+
# and a pattern is set in v2.
|
212
|
+
v2.is_a?(Pattern) ? v1 : v2
|
213
|
+
end
|
214
|
+
# Merge bindings from patterns
|
215
|
+
embedded_solutions = []
|
216
|
+
@bindings.each do |k, v|
|
217
|
+
if v.is_a?(Pattern) && other[k].is_a?(RDF::Statement)
|
218
|
+
embedded_solutions << v.solution(other[k])
|
219
|
+
end
|
220
|
+
end
|
221
|
+
# Merge embedded solutions
|
222
|
+
embedded_solutions.each {|soln| merge!(soln)}
|
204
223
|
self
|
205
224
|
end
|
206
225
|
|
data/lib/rdf/query/solutions.rb
CHANGED
@@ -66,13 +66,15 @@ module RDF; class Query
|
|
66
66
|
#
|
67
67
|
# @return [Array<Symbol>]
|
68
68
|
def variable_names
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
@variable_names ||= begin
|
70
|
+
variables = self.inject({}) do |result, solution|
|
71
|
+
solution.each_name do |name|
|
72
|
+
result[name] ||= true
|
73
|
+
end
|
74
|
+
result
|
72
75
|
end
|
73
|
-
|
76
|
+
variables.keys
|
74
77
|
end
|
75
|
-
variables.keys
|
76
78
|
end
|
77
79
|
|
78
80
|
##
|
@@ -136,6 +138,7 @@ module RDF; class Query
|
|
136
138
|
# @yieldreturn [Boolean]
|
137
139
|
# @return [self]
|
138
140
|
def filter(criteria = {})
|
141
|
+
@variable_names = nil
|
139
142
|
if block_given?
|
140
143
|
self.reject! do |solution|
|
141
144
|
!yield(solution.is_a?(Solution) ? solution : Solution.new(solution))
|
@@ -223,6 +226,13 @@ module RDF; class Query
|
|
223
226
|
solution.bindings.delete_if { |k, v| !variables.include?(k.to_sym) }
|
224
227
|
end
|
225
228
|
end
|
229
|
+
|
230
|
+
# Make sure variable_names are ordered by projected variables
|
231
|
+
projected_vars, vars = variables.map(&:to_sym), variable_names
|
232
|
+
vars = variable_names
|
233
|
+
|
234
|
+
# Maintain projected order, and add any non-projected variables
|
235
|
+
@variable_names = (projected_vars & vars) + (vars - projected_vars)
|
226
236
|
self
|
227
237
|
end
|
228
238
|
alias_method :select, :project
|
data/lib/rdf/query/variable.rb
CHANGED
@@ -157,12 +157,24 @@ class RDF::Query
|
|
157
157
|
##
|
158
158
|
# Rebinds this variable to the given `value`.
|
159
159
|
#
|
160
|
-
# @
|
161
|
-
#
|
160
|
+
# @overload bind(value)
|
161
|
+
# @param [RDF::Query::Solution] value
|
162
|
+
# @return [self] the bound variable
|
163
|
+
#
|
164
|
+
# @overload bind(value)
|
165
|
+
# @param [RDF::Term] value
|
166
|
+
# @return [RDF::Term] the previous value, if any.
|
162
167
|
def bind(value)
|
163
|
-
|
164
|
-
|
165
|
-
|
168
|
+
if value.is_a?(RDF::Query::Solution)
|
169
|
+
self.value = value.to_h.fetch(name, self.value)
|
170
|
+
self
|
171
|
+
else
|
172
|
+
warn "[DEPRECATION] RDF::Query::Variable#bind should be used with a solution, not a term.\n" +
|
173
|
+
"Called from #{Gem.location_of_caller.join(':')}"
|
174
|
+
old_value = self.value
|
175
|
+
self.value = value
|
176
|
+
old_value
|
177
|
+
end
|
166
178
|
end
|
167
179
|
alias_method :bind!, :bind
|
168
180
|
|
data/lib/rdf/reader.rb
CHANGED
@@ -88,9 +88,15 @@ module RDF
|
|
88
88
|
# @yieldreturn [String] another way to provide a sample, allows lazy for retrieving the sample.
|
89
89
|
#
|
90
90
|
# @return [Class]
|
91
|
-
def self.for(
|
92
|
-
|
93
|
-
|
91
|
+
def self.for(*arg, &block)
|
92
|
+
case arg.length
|
93
|
+
when 0 then arg = nil
|
94
|
+
when 1 then arg = arg.first
|
95
|
+
else
|
96
|
+
raise ArgumentError, "Format.for accepts zero or one argument, got #{arg.length}."
|
97
|
+
end
|
98
|
+
arg = arg.merge(has_reader: true) if arg.is_a?(Hash)
|
99
|
+
if format = self.format || Format.for(arg, &block)
|
94
100
|
format.reader
|
95
101
|
end
|
96
102
|
end
|
@@ -115,6 +121,12 @@ module RDF
|
|
115
121
|
# @return [Array<RDF::CLI::Option>]
|
116
122
|
def self.options
|
117
123
|
[
|
124
|
+
RDF::CLI::Option.new(
|
125
|
+
symbol: :base_uri,
|
126
|
+
control: :url,
|
127
|
+
datatype: RDF::URI,
|
128
|
+
on: ["--uri URI"],
|
129
|
+
description: "Base URI of input file, defaults to the filename.") {|arg| RDF::URI(arg)},
|
118
130
|
RDF::CLI::Option.new(
|
119
131
|
symbol: :canonicalize,
|
120
132
|
datatype: TrueClass,
|
@@ -147,11 +159,11 @@ module RDF
|
|
147
159
|
end
|
148
160
|
end,
|
149
161
|
RDF::CLI::Option.new(
|
150
|
-
symbol: :
|
151
|
-
control: :
|
152
|
-
datatype:
|
153
|
-
on: ["--
|
154
|
-
description: "
|
162
|
+
symbol: :rdfstar,
|
163
|
+
control: :select,
|
164
|
+
datatype: [:PG, :SA],
|
165
|
+
on: ["--rdf-star MODE"],
|
166
|
+
description: "Parse RDF*, either in Property Graph mode (PG) or Separate Assertions mode (SA).") {|arg| arg.to_sym},
|
155
167
|
RDF::CLI::Option.new(
|
156
168
|
symbol: :validate,
|
157
169
|
datatype: TrueClass,
|
@@ -206,7 +218,7 @@ module RDF
|
|
206
218
|
headers['Accept'] ||= (self.format.accept_type + %w(*/*;q=0.1)).join(", ")
|
207
219
|
end
|
208
220
|
|
209
|
-
Util::File.open_file(filename, options) do |file|
|
221
|
+
Util::File.open_file(filename, **options) do |file|
|
210
222
|
format_options = options.dup
|
211
223
|
format_options[:content_type] ||= file.content_type if
|
212
224
|
file.respond_to?(:content_type) &&
|
@@ -229,7 +241,7 @@ module RDF
|
|
229
241
|
options[:filename] ||= filename
|
230
242
|
|
231
243
|
if reader
|
232
|
-
reader.new(file, options, &block)
|
244
|
+
reader.new(file, **options, &block)
|
233
245
|
else
|
234
246
|
raise FormatError, "unknown RDF format: #{format_options.inspect}#{"\nThis may be resolved with a require of the 'linkeddata' gem." unless Object.const_defined?(:LinkedData)}"
|
235
247
|
end
|
@@ -255,42 +267,48 @@ module RDF
|
|
255
267
|
#
|
256
268
|
# @param [IO, File, String] input
|
257
269
|
# the input stream to read
|
258
|
-
# @param [
|
259
|
-
# the
|
260
|
-
#
|
261
|
-
# whether to validate the parsed statements and values
|
270
|
+
# @param [#to_s] base_uri (nil)
|
271
|
+
# the base URI to use when resolving relative URIs (not supported by
|
272
|
+
# all readers)
|
262
273
|
# @param [Boolean] canonicalize (false)
|
263
274
|
# whether to canonicalize parsed literals
|
275
|
+
# @param [Encoding] encoding (Encoding::UTF_8)
|
276
|
+
# the encoding of the input stream
|
264
277
|
# @param [Boolean] intern (true)
|
265
278
|
# whether to intern all parsed URIs
|
279
|
+
# @param [:PG, :SA] rdfstar (nil)
|
280
|
+
# support parsing RDF* statement resources.
|
281
|
+
# If `:PG`, referenced statements are also emitted.
|
282
|
+
# If `:SA`, referenced statements are not emitted.
|
266
283
|
# @param [Hash] prefixes (Hash.new)
|
267
284
|
# the prefix mappings to use (not supported by all readers)
|
268
|
-
# @param [#to_s] base_uri (nil)
|
269
|
-
# the base URI to use when resolving relative URIs (not supported by
|
270
|
-
# all readers)
|
271
285
|
# @param [Hash{Symbol => Object}] options
|
272
286
|
# any additional options
|
287
|
+
# @param [Boolean] validate (false)
|
288
|
+
# whether to validate the parsed statements and values
|
273
289
|
# @yield [reader] `self`
|
274
290
|
# @yieldparam [RDF::Reader] reader
|
275
291
|
# @yieldreturn [void] ignored
|
276
292
|
def initialize(input = $stdin,
|
277
|
-
|
278
|
-
validate: false,
|
293
|
+
base_uri: nil,
|
279
294
|
canonicalize: false,
|
295
|
+
encoding: Encoding::UTF_8,
|
280
296
|
intern: true,
|
281
297
|
prefixes: Hash.new,
|
282
|
-
|
298
|
+
rdfstar: nil,
|
299
|
+
validate: false,
|
283
300
|
**options,
|
284
301
|
&block)
|
285
302
|
|
286
303
|
base_uri ||= input.base_uri if input.respond_to?(:base_uri)
|
287
304
|
@options = options.merge({
|
288
|
-
|
289
|
-
validate: validate,
|
305
|
+
base_uri: base_uri,
|
290
306
|
canonicalize: canonicalize,
|
307
|
+
encoding: encoding,
|
291
308
|
intern: intern,
|
292
309
|
prefixes: prefixes,
|
293
|
-
|
310
|
+
rdfstar: rdfstar,
|
311
|
+
validate: validate
|
294
312
|
})
|
295
313
|
|
296
314
|
@input = case input
|
@@ -383,6 +401,9 @@ module RDF
|
|
383
401
|
# Statements are yielded in the order that they are read from the input
|
384
402
|
# stream.
|
385
403
|
#
|
404
|
+
# If the `rdfstar` option is `:PG` and triples include
|
405
|
+
# embedded statements, they are also enumerated.
|
406
|
+
#
|
386
407
|
# @overload each_statement
|
387
408
|
# @yield [statement]
|
388
409
|
# each statement
|
@@ -399,7 +420,11 @@ module RDF
|
|
399
420
|
def each_statement(&block)
|
400
421
|
if block_given?
|
401
422
|
begin
|
402
|
-
loop
|
423
|
+
loop do
|
424
|
+
st = read_statement
|
425
|
+
block.call(st)
|
426
|
+
each_pg_statement(st, &block) if options[:rdfstar] == :PG
|
427
|
+
end
|
403
428
|
rescue EOFError
|
404
429
|
rewind rescue nil
|
405
430
|
end
|
@@ -416,6 +441,9 @@ module RDF
|
|
416
441
|
# Triples are yielded in the order that they are read from the input
|
417
442
|
# stream.
|
418
443
|
#
|
444
|
+
# If the `rdfstar` option is `:PG` and triples include
|
445
|
+
# embedded statements, they are also enumerated.
|
446
|
+
#
|
419
447
|
# @overload each_triple
|
420
448
|
# @yield [subject, predicate, object]
|
421
449
|
# each triple
|
@@ -433,7 +461,14 @@ module RDF
|
|
433
461
|
def each_triple(&block)
|
434
462
|
if block_given?
|
435
463
|
begin
|
436
|
-
loop
|
464
|
+
loop do
|
465
|
+
triple = read_triple
|
466
|
+
block.call(*triple)
|
467
|
+
if options[:rdfstar] == :PG
|
468
|
+
block.call(*triple[0].to_a) if triple[0].is_a?(Statement)
|
469
|
+
block.call(*triple[2].to_a) if triple[2].is_a?(Statement)
|
470
|
+
end
|
471
|
+
end
|
437
472
|
rescue EOFError
|
438
473
|
rewind rescue nil
|
439
474
|
end
|
@@ -544,6 +579,22 @@ module RDF
|
|
544
579
|
log_error("Expected object (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
|
545
580
|
end
|
546
581
|
|
582
|
+
##
|
583
|
+
# Recursively emit embedded statements in Property Graph mode
|
584
|
+
#
|
585
|
+
# @param [RDF::Statement] statement
|
586
|
+
def each_pg_statement(statement, &block)
|
587
|
+
if statement.subject.is_a?(Statement)
|
588
|
+
block.call(statement.subject)
|
589
|
+
each_pg_statement(statement.subject, &block)
|
590
|
+
end
|
591
|
+
|
592
|
+
if statement.object.is_a?(Statement)
|
593
|
+
block.call(statement.object)
|
594
|
+
each_pg_statement(statement.object, &block)
|
595
|
+
end
|
596
|
+
end
|
597
|
+
|
547
598
|
public
|
548
599
|
##
|
549
600
|
# Returns the encoding of the input stream.
|
data/lib/rdf/repository.rb
CHANGED
@@ -119,9 +119,9 @@ module RDF
|
|
119
119
|
# @yieldparam [Repository]
|
120
120
|
# @return [void]
|
121
121
|
def self.load(urls, **options, &block)
|
122
|
-
self.new(options) do |repository|
|
122
|
+
self.new(**options) do |repository|
|
123
123
|
Array(urls).each do |url|
|
124
|
-
repository.load(url, options)
|
124
|
+
repository.load(url, **options)
|
125
125
|
end
|
126
126
|
|
127
127
|
if block_given?
|
@@ -182,6 +182,7 @@ module RDF
|
|
182
182
|
when :validity then @options.fetch(:with_validity, true)
|
183
183
|
when :literal_equality then true
|
184
184
|
when :atomic_write then false
|
185
|
+
when :rdfstar then false
|
185
186
|
when :snapshots then false
|
186
187
|
else false
|
187
188
|
end
|
@@ -266,6 +267,7 @@ module RDF
|
|
266
267
|
when :validity then @options.fetch(:with_validity, true)
|
267
268
|
when :literal_equality then true
|
268
269
|
when :atomic_write then true
|
270
|
+
when :rdfstar then true
|
269
271
|
when :snapshots then true
|
270
272
|
else false
|
271
273
|
end
|
@@ -340,7 +342,14 @@ module RDF
|
|
340
342
|
# @see Mutable#apply_changeset
|
341
343
|
def apply_changeset(changeset)
|
342
344
|
data = @data
|
343
|
-
changeset.deletes.each
|
345
|
+
changeset.deletes.each do |del|
|
346
|
+
if del.constant?
|
347
|
+
data = delete_from(data, del)
|
348
|
+
else
|
349
|
+
# we need this condition to handle wildcard statements
|
350
|
+
query_pattern(del) { |stmt| data = delete_from(data, stmt) }
|
351
|
+
end
|
352
|
+
end
|
344
353
|
changeset.inserts.each { |ins| data = insert_to(data, ins) }
|
345
354
|
@data = data
|
346
355
|
end
|
@@ -388,20 +397,25 @@ module RDF
|
|
388
397
|
graph_name.eql?(c)
|
389
398
|
|
390
399
|
ss = if subject.nil? || subject.is_a?(RDF::Query::Variable)
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
400
|
+
ss
|
401
|
+
elsif subject.is_a?(RDF::Query::Pattern)
|
402
|
+
# Match subjects which are statements matching this pattern
|
403
|
+
ss.keys.select {|s| s.statement? && subject.eql?(s)}.inject({}) do |memo, st|
|
404
|
+
memo.merge(st => ss[st])
|
405
|
+
end
|
406
|
+
elsif ss.has_key?(subject)
|
407
|
+
{ subject => ss[subject] }
|
408
|
+
else
|
409
|
+
[]
|
410
|
+
end
|
397
411
|
ss.each do |s, ps|
|
398
412
|
ps = if predicate.nil? || predicate.is_a?(RDF::Query::Variable)
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
413
|
+
ps
|
414
|
+
elsif ps.has_key?(predicate)
|
415
|
+
{ predicate => ps[predicate] }
|
416
|
+
else
|
417
|
+
[]
|
418
|
+
end
|
405
419
|
ps.each do |p, os|
|
406
420
|
os.each do |o, object_options|
|
407
421
|
next unless object.nil? || object.eql?(o)
|
@@ -411,7 +425,7 @@ module RDF
|
|
411
425
|
end
|
412
426
|
end
|
413
427
|
else
|
414
|
-
enum_for(:query_pattern, pattern, options)
|
428
|
+
enum_for(:query_pattern, pattern, **options)
|
415
429
|
end
|
416
430
|
end
|
417
431
|
|
@@ -512,8 +526,8 @@ module RDF
|
|
512
526
|
class SerializedTransaction < Transaction
|
513
527
|
##
|
514
528
|
# @see Transaction#initialize
|
515
|
-
def initialize(*)
|
516
|
-
super
|
529
|
+
def initialize(*args, **options, &block)
|
530
|
+
super(*args, **options, &block)
|
517
531
|
@base_snapshot = @snapshot
|
518
532
|
end
|
519
533
|
|
data/lib/rdf/transaction.rb
CHANGED
@@ -24,7 +24,7 @@ module RDF
|
|
24
24
|
# repository = RDF::Repository.new
|
25
25
|
#
|
26
26
|
# RDF::Transaction.begin(repository) do |tx|
|
27
|
-
# tx.query(predicate: RDF::Vocab::DOAP.developer) do |statement|
|
27
|
+
# tx.query({predicate: RDF::Vocab::DOAP.developer}) do |statement|
|
28
28
|
# puts statement.inspect
|
29
29
|
# end
|
30
30
|
# end
|
data/lib/rdf/util.rb
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
module RDF; module Util
|
2
|
-
autoload :Aliasing,
|
3
|
-
autoload :Cache,
|
4
|
-
autoload :File,
|
5
|
-
autoload :Logger,
|
6
|
-
autoload :UUID,
|
2
|
+
autoload :Aliasing, 'rdf/util/aliasing'
|
3
|
+
autoload :Cache, 'rdf/util/cache'
|
4
|
+
autoload :File, 'rdf/util/file'
|
5
|
+
autoload :Logger, 'rdf/util/logger'
|
6
|
+
autoload :UUID, 'rdf/util/uuid'
|
7
|
+
autoload :Coercions, 'rdf/util/coercions'
|
7
8
|
end; end
|
data/lib/rdf/util/cache.rb
CHANGED
@@ -9,8 +9,8 @@ module RDF; module Util
|
|
9
9
|
#
|
10
10
|
# While this cache is something of an internal implementation detail of
|
11
11
|
# RDF.rb, some external libraries do currently make use of it as well,
|
12
|
-
# including [SPARQL](
|
13
|
-
# [Spira](
|
12
|
+
# including [SPARQL](https://github.com/ruby-rdf/sparql/) and
|
13
|
+
# [Spira](https://github.com/ruby-rdf/spira). Do be sure to include any changes
|
14
14
|
# here in the RDF.rb changelog.
|
15
15
|
#
|
16
16
|
# @see RDF::URI.intern
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module RDF
|
3
|
+
module Util
|
4
|
+
module Coercions
|
5
|
+
# This is a provisional module intended to house input
|
6
|
+
# coercions. Currently the only coercion is a statement
|
7
|
+
# preprocessor that is used in e.g. {RDF::Writable#insert} and
|
8
|
+
# {RDF::Mutable#delete}.
|
9
|
+
|
10
|
+
protected
|
11
|
+
|
12
|
+
##
|
13
|
+
# Coerce an array of arguments into {RDF::Statement}, or
|
14
|
+
# {RDF::Enumerable} and then yield to a block. Note that this
|
15
|
+
# code was amalgamated from that which was sandwiched around
|
16
|
+
# both {RDF::Writable#insert_statements} and
|
17
|
+
# {RDF::Mutable#delete_statements}. The parameters `query` and
|
18
|
+
# `constant` are therefore present to handle the conditions
|
19
|
+
# where the statements contain wildcards and what to do about
|
20
|
+
# them.
|
21
|
+
#
|
22
|
+
# @example
|
23
|
+
# coerce_statements(statements) { |value| do_something(value) }
|
24
|
+
#
|
25
|
+
# @param statements [#map] The arbitrary-ish input to be manipulated
|
26
|
+
# @param query [false, true] Whether to call `query` before the block
|
27
|
+
# (as expected by {Mutable#delete_statements})
|
28
|
+
# @param constant [false, true] Whether to test if the statements
|
29
|
+
# are constant (as expected by {Mutable#delete_statements})
|
30
|
+
# @yield [RDF::Statement, RDF::Enumerable]
|
31
|
+
# @return statements
|
32
|
+
def coerce_statements(statements, query: false, constant: false, &block)
|
33
|
+
raise ArgumentError, 'expecting a block' unless block_given?
|
34
|
+
|
35
|
+
statements = statements.map do |value|
|
36
|
+
case
|
37
|
+
when value.respond_to?(:each_statement)
|
38
|
+
block.call(value)
|
39
|
+
nil
|
40
|
+
when (statement = Statement.from(value)) &&
|
41
|
+
(!constant || statement.constant?)
|
42
|
+
statement
|
43
|
+
when query
|
44
|
+
# XXX note that this only makes sense when the module is include()d
|
45
|
+
block.call(self.query(value))
|
46
|
+
nil
|
47
|
+
else
|
48
|
+
raise ArgumentError, "Not a valid statement: #{value.inspect}"
|
49
|
+
end
|
50
|
+
end.compact
|
51
|
+
|
52
|
+
block.call(statements) unless statements.empty?
|
53
|
+
|
54
|
+
# eh might as well return these
|
55
|
+
statements
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|