rdf 3.0.12 → 3.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/AUTHORS +1 -1
- data/README.md +46 -11
- data/VERSION +1 -1
- data/etc/doap.nt +74 -80
- data/lib/rdf.rb +35 -23
- data/lib/rdf/changeset.rb +87 -19
- data/lib/rdf/cli.rb +7 -7
- data/lib/rdf/format.rb +17 -10
- data/lib/rdf/mixin/enumerable.rb +3 -2
- data/lib/rdf/mixin/mutable.rb +5 -15
- data/lib/rdf/mixin/queryable.rb +12 -4
- data/lib/rdf/mixin/writable.rb +9 -14
- data/lib/rdf/model/dataset.rb +1 -1
- data/lib/rdf/model/graph.rb +5 -2
- data/lib/rdf/model/list.rb +5 -5
- data/lib/rdf/model/literal.rb +3 -3
- data/lib/rdf/model/statement.rb +30 -7
- data/lib/rdf/model/uri.rb +44 -23
- data/lib/rdf/nquads.rb +6 -6
- data/lib/rdf/ntriples.rb +6 -4
- 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/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 +108 -14
- data/lib/rdf/writer.rb +32 -10
- metadata +32 -27
data/lib/rdf/model/uri.rb
CHANGED
@@ -141,8 +141,8 @@ module RDF
|
|
141
141
|
#
|
142
142
|
# (see #initialize)
|
143
143
|
# @return [RDF::URI] an immutable, frozen URI object
|
144
|
-
def self.intern(str, *args)
|
145
|
-
(cache[(str = str.to_s).to_sym] ||= self.new(str, *args)).freeze
|
144
|
+
def self.intern(str, *args, **options)
|
145
|
+
(cache[(str = str.to_s).to_sym] ||= self.new(str, *args, **options)).freeze
|
146
146
|
end
|
147
147
|
|
148
148
|
##
|
@@ -225,11 +225,9 @@ module RDF
|
|
225
225
|
@mutex = Mutex.new
|
226
226
|
uri = args.first
|
227
227
|
if uri
|
228
|
-
@value = uri.to_s
|
229
|
-
if @value.encoding != Encoding::UTF_8
|
230
|
-
|
231
|
-
@value.freeze
|
232
|
-
end
|
228
|
+
@value = uri.to_s.dup
|
229
|
+
@value.dup.force_encoding(Encoding::UTF_8) if @value.encoding != Encoding::UTF_8
|
230
|
+
@value.freeze
|
233
231
|
else
|
234
232
|
%w(
|
235
233
|
scheme
|
@@ -402,7 +400,7 @@ module RDF
|
|
402
400
|
# @example Joining two URIs
|
403
401
|
# RDF::URI.new('http://example.org/foo/bar').join('/foo')
|
404
402
|
# #=> RDF::URI('http://example.org/foo')
|
405
|
-
# @see <
|
403
|
+
# @see <https://github.com/ruby-rdf/rdf-spec/blob/master/lib/rdf/spec/uri.rb>
|
406
404
|
# @see <http://tools.ietf.org/html/rfc3986#section-5.2>
|
407
405
|
# @see RDF::URI#/
|
408
406
|
# @see RDF::URI#+
|
@@ -431,7 +429,9 @@ module RDF
|
|
431
429
|
joined_parts[:query] = uri.query
|
432
430
|
else
|
433
431
|
# Merge path segments from section 5.2.3
|
434
|
-
|
432
|
+
# Note that if the path includes no segments, the entire path is removed
|
433
|
+
# > return a string consisting of the reference's path component appended to all but the last segment of the base URI's path (i.e., excluding any characters after the right-most "/" in the base URI path, or excluding the entire base URI path if it does not contain any "/" characters).
|
434
|
+
base_path = path.to_s.include?('/') ? path.to_s.sub(/\/[^\/]*$/, '/') : ''
|
435
435
|
joined_parts[:path] = self.class.normalize_path(base_path + uri.path)
|
436
436
|
joined_parts[:query] = uri.query
|
437
437
|
end
|
@@ -439,7 +439,7 @@ module RDF
|
|
439
439
|
end
|
440
440
|
|
441
441
|
# Return joined URI
|
442
|
-
RDF::URI.new(joined_parts)
|
442
|
+
RDF::URI.new(**joined_parts)
|
443
443
|
end
|
444
444
|
|
445
445
|
##
|
@@ -471,7 +471,7 @@ module RDF
|
|
471
471
|
# @see RDF::URI#+
|
472
472
|
# @see RDF::URI#join
|
473
473
|
# @see <http://tools.ietf.org/html/rfc3986#section-5.2>
|
474
|
-
# @see <
|
474
|
+
# @see <https://github.com/ruby-rdf/rdf-spec/blob/master/lib/rdf/spec/uri.rb>
|
475
475
|
# @example Building a HTTP URL
|
476
476
|
# RDF::URI.new('http://example.org') / 'jhacker' / 'foaf.ttl'
|
477
477
|
# #=> RDF::URI('http://example.org/jhacker/foaf.ttl')
|
@@ -507,7 +507,7 @@ module RDF
|
|
507
507
|
case fragment.to_s[0,1]
|
508
508
|
when '#'
|
509
509
|
# Base ending with '/', fragment beginning with '#'. The fragment wins, we use '#'.
|
510
|
-
res.path = res.path.to_s.sub
|
510
|
+
res.path = res.path.to_s.sub(/\/*$/, '')
|
511
511
|
# Add fragment
|
512
512
|
res.fragment = fragment.to_s.sub(/^#+/,'')
|
513
513
|
else
|
@@ -572,7 +572,7 @@ module RDF
|
|
572
572
|
self
|
573
573
|
else
|
574
574
|
RDF::URI.new(
|
575
|
-
object.merge(path: '/').
|
575
|
+
**object.merge(path: '/').
|
576
576
|
keep_if {|k, v| [:scheme, :authority, :path].include?(k)})
|
577
577
|
end
|
578
578
|
end
|
@@ -657,7 +657,7 @@ module RDF
|
|
657
657
|
#
|
658
658
|
# @return [RDF::URI]
|
659
659
|
def dup
|
660
|
-
self.class.new(
|
660
|
+
self.class.new(@value, **(@object || {}))
|
661
661
|
end
|
662
662
|
|
663
663
|
##
|
@@ -846,7 +846,7 @@ module RDF
|
|
846
846
|
parts[:user] = (user.dup.force_encoding(Encoding::UTF_8) if user)
|
847
847
|
parts[:password] = (password.dup.force_encoding(Encoding::UTF_8) if password)
|
848
848
|
parts[:host] = (host.dup.force_encoding(Encoding::UTF_8) if host)
|
849
|
-
parts[:port] = (
|
849
|
+
parts[:port] = (URI.decode(port).to_i if port)
|
850
850
|
parts[:path] = (path.to_s.dup.force_encoding(Encoding::UTF_8) unless path.empty?)
|
851
851
|
parts[:query] = (query[1..-1].dup.force_encoding(Encoding::UTF_8) if query)
|
852
852
|
parts[:fragment] = (fragment[1..-1].dup.force_encoding(Encoding::UTF_8) if fragment)
|
@@ -902,7 +902,7 @@ module RDF
|
|
902
902
|
# Normalized version of user
|
903
903
|
# @return [String]
|
904
904
|
def normalized_user
|
905
|
-
|
905
|
+
URI.encode(URI.decode(user), /[^#{IUNRESERVED}|#{SUB_DELIMS}]/) if user
|
906
906
|
end
|
907
907
|
|
908
908
|
##
|
@@ -928,7 +928,7 @@ module RDF
|
|
928
928
|
# Normalized version of password
|
929
929
|
# @return [String]
|
930
930
|
def normalized_password
|
931
|
-
|
931
|
+
URI.encode(URI.decode(password), /[^#{IUNRESERVED}|#{SUB_DELIMS}]/) if password
|
932
932
|
end
|
933
933
|
|
934
934
|
HOST_FROM_AUTHORITY_RE = /(?:[^@]+@)?([^:]+)(?::.*)?$/.freeze
|
@@ -937,7 +937,7 @@ module RDF
|
|
937
937
|
# @return [String]
|
938
938
|
def host
|
939
939
|
object.fetch(:host) do
|
940
|
-
@object[:host] = ($1 if HOST_FROM_AUTHORITY_RE.match(@object[:authority]))
|
940
|
+
@object[:host] = ($1 if @object[:authority] && HOST_FROM_AUTHORITY_RE.match(@object[:authority]))
|
941
941
|
end
|
942
942
|
end
|
943
943
|
|
@@ -965,7 +965,7 @@ module RDF
|
|
965
965
|
# @return [String]
|
966
966
|
def port
|
967
967
|
object.fetch(:port) do
|
968
|
-
@object[:port] = ($1 if PORT_FROM_AUTHORITY_RE.match(@object[:authority]))
|
968
|
+
@object[:port] = ($1 if @object[:authority] && PORT_FROM_AUTHORITY_RE.match(@object[:authority]))
|
969
969
|
end
|
970
970
|
end
|
971
971
|
|
@@ -1180,8 +1180,8 @@ module RDF
|
|
1180
1180
|
inject(return_type == Hash ? {} : []) do |memo,kv|
|
1181
1181
|
k,v = kv.to_s.split('=', 2)
|
1182
1182
|
next if k.to_s.empty?
|
1183
|
-
k =
|
1184
|
-
v =
|
1183
|
+
k = URI.decode(k)
|
1184
|
+
v = URI.decode(v) if v
|
1185
1185
|
if return_type == Hash
|
1186
1186
|
case memo[k]
|
1187
1187
|
when nil then memo[k] = v
|
@@ -1293,9 +1293,9 @@ module RDF
|
|
1293
1293
|
def normalize_segment(value, expr, downcase = false)
|
1294
1294
|
if value
|
1295
1295
|
value = value.dup.force_encoding(Encoding::UTF_8)
|
1296
|
-
decoded =
|
1296
|
+
decoded = URI.decode(value)
|
1297
1297
|
decoded.downcase! if downcase
|
1298
|
-
|
1298
|
+
URI.encode(decoded, /[^(?:#{expr})]/)
|
1299
1299
|
end
|
1300
1300
|
end
|
1301
1301
|
|
@@ -1314,6 +1314,27 @@ module RDF
|
|
1314
1314
|
""
|
1315
1315
|
end
|
1316
1316
|
end
|
1317
|
+
|
1318
|
+
# URI encode matching characters in value
|
1319
|
+
# From URI gem, as this is now generally deprecated
|
1320
|
+
def self.encode(str, expr)
|
1321
|
+
str.gsub(expr) do
|
1322
|
+
us = $&
|
1323
|
+
tmp = ''
|
1324
|
+
us.each_byte do |uc|
|
1325
|
+
tmp << sprintf('%%%02X', uc)
|
1326
|
+
end
|
1327
|
+
tmp
|
1328
|
+
end.force_encoding(Encoding::US_ASCII)
|
1329
|
+
end
|
1330
|
+
|
1331
|
+
# URI decode escape sequences in value
|
1332
|
+
# From URI gem, as this is now generally deprecated
|
1333
|
+
def self.decode(str)
|
1334
|
+
enc = str.encoding
|
1335
|
+
enc = Encoding::UTF_8 if enc == Encoding::US_ASCII
|
1336
|
+
str.gsub(PCT_ENCODED) { [$&[1, 2]].pack('H2').force_encoding(enc) }
|
1337
|
+
end
|
1317
1338
|
end
|
1318
1339
|
|
1319
1340
|
# RDF::IRI is a synonym for RDF::URI
|
data/lib/rdf/nquads.rb
CHANGED
@@ -69,9 +69,9 @@ module RDF
|
|
69
69
|
|
70
70
|
begin
|
71
71
|
unless blank? || read_comment
|
72
|
-
subject = read_uriref || read_node || fail_subject
|
72
|
+
subject = read_uriref || read_node || read_rdfstar || fail_subject
|
73
73
|
predicate = read_uriref(intern: true) || fail_predicate
|
74
|
-
object = read_uriref || read_node || read_literal || fail_object
|
74
|
+
object = read_uriref || read_node || read_literal || read_rdfstar || fail_object
|
75
75
|
graph_name = read_uriref || read_node
|
76
76
|
if validate? && !read_eos
|
77
77
|
log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
|
@@ -96,7 +96,7 @@ module RDF
|
|
96
96
|
# @param [RDF::Term] object
|
97
97
|
# @return [void]
|
98
98
|
def write_quad(subject, predicate, object, graph_name)
|
99
|
-
puts format_quad(subject, predicate, object, graph_name,
|
99
|
+
puts format_quad(subject, predicate, object, graph_name, **@options)
|
100
100
|
end
|
101
101
|
|
102
102
|
##
|
@@ -107,7 +107,7 @@ module RDF
|
|
107
107
|
# @return [String]
|
108
108
|
# @since 0.4.0
|
109
109
|
def format_statement(statement, **options)
|
110
|
-
format_quad(*statement.to_quad, options)
|
110
|
+
format_quad(*statement.to_quad, **options)
|
111
111
|
end
|
112
112
|
|
113
113
|
##
|
@@ -120,8 +120,8 @@ module RDF
|
|
120
120
|
# @param [Hash{Symbol => Object}] options = ({})
|
121
121
|
# @return [String]
|
122
122
|
def format_quad(subject, predicate, object, graph_name, **options)
|
123
|
-
s = "%s %s %s " % [subject, predicate, object].map { |value| format_term(value, options) }
|
124
|
-
s += format_term(graph_name, options) + " " if graph_name
|
123
|
+
s = "%s %s %s " % [subject, predicate, object].map { |value| format_term(value, **options) }
|
124
|
+
s += format_term(graph_name, **options) + " " if graph_name
|
125
125
|
s + "."
|
126
126
|
end
|
127
127
|
end # Writer
|
data/lib/rdf/ntriples.rb
CHANGED
@@ -15,15 +15,17 @@ module RDF
|
|
15
15
|
#
|
16
16
|
# <https://rubygems.org/gems/rdf> <http://purl.org/dc/terms/title> "rdf" .
|
17
17
|
#
|
18
|
-
#
|
19
|
-
#
|
18
|
+
# ## RDFStar (RDF*)
|
19
|
+
#
|
20
|
+
# Supports statements as resources using `<<s p o>>`.
|
21
|
+
#
|
22
|
+
# ## Installation
|
20
23
|
#
|
21
24
|
# This is the only RDF serialization format that is directly supported by
|
22
25
|
# RDF.rb. Support for other formats is available in the form of add-on
|
23
26
|
# gems, e.g. 'rdf-xml' or 'rdf-json'.
|
24
27
|
#
|
25
|
-
# Documentation
|
26
|
-
# -------------
|
28
|
+
# ## Documentation
|
27
29
|
#
|
28
30
|
# * {RDF::NTriples::Format}
|
29
31
|
# * {RDF::NTriples::Reader}
|
data/lib/rdf/ntriples/reader.rb
CHANGED
@@ -25,6 +25,10 @@ module RDF::NTriples
|
|
25
25
|
# end
|
26
26
|
# end
|
27
27
|
#
|
28
|
+
# ** RDFStar (RDF*)
|
29
|
+
#
|
30
|
+
# Supports statements as resources using `<<s p o>>`.
|
31
|
+
#
|
28
32
|
# @see http://www.w3.org/TR/rdf-testcases/#ntriples
|
29
33
|
# @see http://www.w3.org/TR/n-triples/
|
30
34
|
class Reader < RDF::Reader
|
@@ -70,6 +74,10 @@ module RDF::NTriples
|
|
70
74
|
# 22
|
71
75
|
STRING_LITERAL_QUOTE = /"((?:[^\"\\\n\r]|#{ECHAR}|#{UCHAR})*)"/.freeze
|
72
76
|
|
77
|
+
# RDF*
|
78
|
+
ST_START = /^<</.freeze
|
79
|
+
ST_END = /^\s*>>/.freeze
|
80
|
+
|
73
81
|
# @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar
|
74
82
|
COMMENT = /^#\s*(.*)$/.freeze
|
75
83
|
NODEID = /^#{BLANK_NODE_LABEL}/.freeze
|
@@ -96,7 +104,7 @@ module RDF::NTriples
|
|
96
104
|
def self.unserialize(input, **options)
|
97
105
|
case input
|
98
106
|
when nil then nil
|
99
|
-
else self.new(input,
|
107
|
+
else self.new(input, logger: [], **options).read_value
|
100
108
|
end
|
101
109
|
end
|
102
110
|
|
@@ -104,20 +112,20 @@ module RDF::NTriples
|
|
104
112
|
# (see unserialize)
|
105
113
|
# @return [RDF::Resource]
|
106
114
|
def self.parse_subject(input, **options)
|
107
|
-
parse_uri(input, options) || parse_node(input, options)
|
115
|
+
parse_uri(input, **options) || parse_node(input, **options)
|
108
116
|
end
|
109
117
|
|
110
118
|
##
|
111
119
|
# (see unserialize)
|
112
120
|
# @return [RDF::URI]
|
113
|
-
def self.parse_predicate(input,
|
121
|
+
def self.parse_predicate(input, **options)
|
114
122
|
parse_uri(input, intern: true)
|
115
123
|
end
|
116
124
|
|
117
125
|
##
|
118
126
|
# (see unserialize)
|
119
127
|
def self.parse_object(input, **options)
|
120
|
-
parse_uri(input, options) || parse_node(input, options) || parse_literal(input, options)
|
128
|
+
parse_uri(input, **options) || parse_node(input, **options) || parse_literal(input, **options)
|
121
129
|
end
|
122
130
|
|
123
131
|
##
|
@@ -202,7 +210,7 @@ module RDF::NTriples
|
|
202
210
|
begin
|
203
211
|
read_statement
|
204
212
|
rescue RDF::ReaderError
|
205
|
-
value = read_uriref || read_node || read_literal
|
213
|
+
value = read_uriref || read_node || read_literal || read_rdfstar
|
206
214
|
log_recover
|
207
215
|
value
|
208
216
|
end
|
@@ -218,9 +226,9 @@ module RDF::NTriples
|
|
218
226
|
|
219
227
|
begin
|
220
228
|
unless blank? || read_comment
|
221
|
-
subject = read_uriref || read_node || fail_subject
|
229
|
+
subject = read_uriref || read_node || read_rdfstar || fail_subject
|
222
230
|
predicate = read_uriref(intern: true) || fail_predicate
|
223
|
-
object = read_uriref || read_node || read_literal || fail_object
|
231
|
+
object = read_uriref || read_node || read_literal || read_rdfstar || fail_object
|
224
232
|
|
225
233
|
if validate? && !read_eos
|
226
234
|
log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
|
@@ -234,6 +242,20 @@ module RDF::NTriples
|
|
234
242
|
end
|
235
243
|
end
|
236
244
|
|
245
|
+
##
|
246
|
+
# @return [RDF::Statement]
|
247
|
+
def read_rdfstar
|
248
|
+
if @options[:rdfstar] && match(ST_START)
|
249
|
+
subject = read_uriref || read_node || read_rdfstar || fail_subject
|
250
|
+
predicate = read_uriref(intern: true) || fail_predicate
|
251
|
+
object = read_uriref || read_node || read_literal || read_rdfstar || fail_object
|
252
|
+
if !match(ST_END)
|
253
|
+
log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
|
254
|
+
end
|
255
|
+
RDF::Statement.new(subject, predicate, object)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
|
237
259
|
##
|
238
260
|
# @return [Boolean]
|
239
261
|
# @see http://www.w3.org/TR/rdf-testcases/#ntrip_grammar (comment)
|
data/lib/rdf/ntriples/writer.rb
CHANGED
@@ -208,7 +208,7 @@ module RDF::NTriples
|
|
208
208
|
# @param [RDF::Term] object
|
209
209
|
# @return [void]
|
210
210
|
def write_triple(subject, predicate, object)
|
211
|
-
puts format_triple(subject, predicate, object,
|
211
|
+
puts format_triple(subject, predicate, object, **@options)
|
212
212
|
end
|
213
213
|
|
214
214
|
##
|
@@ -221,6 +221,15 @@ module RDF::NTriples
|
|
221
221
|
format_triple(*statement.to_triple, **options)
|
222
222
|
end
|
223
223
|
|
224
|
+
##
|
225
|
+
# Returns the N-Triples representation of an RDF* reified statement.
|
226
|
+
#
|
227
|
+
# @param [RDF::Statement] statement
|
228
|
+
# @param [Hash{Symbol => Object}] options ({})
|
229
|
+
# @return [String]
|
230
|
+
def format_rdfstar(statement, **options)
|
231
|
+
"<<%s %s %s>>" % statement.to_a.map { |value| format_term(value, **options) }
|
232
|
+
end
|
224
233
|
##
|
225
234
|
# Returns the N-Triples representation of a triple.
|
226
235
|
#
|
data/lib/rdf/query.rb
CHANGED
@@ -90,7 +90,7 @@ module RDF
|
|
90
90
|
# the resulting solution sequence
|
91
91
|
# @see RDF::Query#execute
|
92
92
|
def self.execute(queryable, patterns = {}, options = {}, &block)
|
93
|
-
self.new(patterns, options, &block).execute(queryable, options)
|
93
|
+
self.new(patterns, **options, &block).execute(queryable, **options)
|
94
94
|
end
|
95
95
|
|
96
96
|
##
|
@@ -134,6 +134,12 @@ module RDF
|
|
134
134
|
# @return [Hash]
|
135
135
|
attr_reader :options
|
136
136
|
|
137
|
+
##
|
138
|
+
# Scope the query to named graphs matching value
|
139
|
+
#
|
140
|
+
# @return [RDF::Resource, RDF::Query::Variable, false] graph_name
|
141
|
+
attr_accessor :graph_name
|
142
|
+
|
137
143
|
##
|
138
144
|
# Initializes a new basic graph pattern query.
|
139
145
|
#
|
@@ -180,6 +186,7 @@ module RDF
|
|
180
186
|
@options = options.dup
|
181
187
|
@solutions = Query::Solutions(solutions)
|
182
188
|
graph_name = name if graph_name.nil?
|
189
|
+
@graph_name = graph_name
|
183
190
|
|
184
191
|
patterns << @options if patterns.empty?
|
185
192
|
|
@@ -189,8 +196,6 @@ module RDF
|
|
189
196
|
else patterns
|
190
197
|
end
|
191
198
|
|
192
|
-
self.graph_name = graph_name
|
193
|
-
|
194
199
|
if block_given?
|
195
200
|
case block.arity
|
196
201
|
when 1 then block.call(self)
|
@@ -223,7 +228,7 @@ module RDF
|
|
223
228
|
# whether this is an optional pattern
|
224
229
|
# @return [void] self
|
225
230
|
def pattern(pattern, **options)
|
226
|
-
@patterns << Pattern.from(pattern, options)
|
231
|
+
@patterns << Pattern.from(pattern, **options)
|
227
232
|
self
|
228
233
|
end
|
229
234
|
|
@@ -235,7 +240,7 @@ module RDF
|
|
235
240
|
# @return [RDF::Query] a copy of `self`
|
236
241
|
# @since 0.3.0
|
237
242
|
def optimize(**options)
|
238
|
-
self.dup.optimize!(options)
|
243
|
+
self.dup.optimize!(**options)
|
239
244
|
end
|
240
245
|
|
241
246
|
##
|
@@ -284,6 +289,8 @@ module RDF
|
|
284
289
|
# any additional keyword options
|
285
290
|
# @option options [Hash{Symbol => RDF::Term}] bindings
|
286
291
|
# optional variable bindings to use
|
292
|
+
# @option options [Boolean] :optimize
|
293
|
+
# Optimize query before execution.
|
287
294
|
# @option options [RDF::Query::Solutions] solutions
|
288
295
|
# optional initial solutions for chained queries
|
289
296
|
# @yield [solution]
|
@@ -294,9 +301,7 @@ module RDF
|
|
294
301
|
# the resulting solution sequence
|
295
302
|
# @see http://www.holygoat.co.uk/blog/entry/2005-10-25-1
|
296
303
|
# @see http://www.w3.org/TR/sparql11-query/#emptyGroupPattern
|
297
|
-
def execute(queryable, solutions: Solution.new, graph_name: nil, name: nil, **options, &block)
|
298
|
-
options = {bindings: {}}.merge(options)
|
299
|
-
|
304
|
+
def execute(queryable, bindings: {}, solutions: Solution.new, graph_name: nil, name: nil, **options, &block)
|
300
305
|
# Use provided solutions to allow for query chaining
|
301
306
|
# Otherwise, a quick empty solution simplifies the logic below; no special case for
|
302
307
|
# the first pattern
|
@@ -308,17 +313,17 @@ module RDF
|
|
308
313
|
return @solutions
|
309
314
|
end
|
310
315
|
|
316
|
+
self.optimize! if options[:optimize]
|
311
317
|
patterns = @patterns
|
312
318
|
graph_name = name if graph_name.nil?
|
313
|
-
graph_name =
|
314
|
-
options[:graph_name] = graph_name unless graph_name.nil?
|
319
|
+
@graph_name = graph_name unless graph_name.nil?
|
315
320
|
|
316
321
|
# Add graph_name to pattern, if necessary
|
317
|
-
unless graph_name.nil?
|
322
|
+
unless @graph_name.nil?
|
318
323
|
if patterns.empty?
|
319
|
-
patterns = [Pattern.new(nil, nil, nil, graph_name: graph_name)]
|
324
|
+
patterns = [Pattern.new(nil, nil, nil, graph_name: @graph_name)]
|
320
325
|
else
|
321
|
-
apply_graph_name(graph_name)
|
326
|
+
apply_graph_name(@graph_name)
|
322
327
|
end
|
323
328
|
end
|
324
329
|
|
@@ -326,15 +331,15 @@ module RDF
|
|
326
331
|
|
327
332
|
old_solutions, @solutions = @solutions, Query::Solutions()
|
328
333
|
|
329
|
-
|
334
|
+
bindings.each_key do |variable|
|
330
335
|
if pattern.variables.include?(variable)
|
331
336
|
unbound_solutions, old_solutions = old_solutions, Query::Solutions()
|
332
|
-
|
337
|
+
bindings[variable].each do |binding|
|
333
338
|
unbound_solutions.each do |solution|
|
334
339
|
old_solutions << solution.merge(variable => binding)
|
335
340
|
end
|
336
341
|
end
|
337
|
-
|
342
|
+
bindings.delete(variable)
|
338
343
|
end
|
339
344
|
end
|
340
345
|
|
@@ -407,38 +412,26 @@ module RDF
|
|
407
412
|
# Is this query scoped to a named graph?
|
408
413
|
# @return [Boolean]
|
409
414
|
def named?
|
410
|
-
!!
|
415
|
+
!!graph_name
|
411
416
|
end
|
412
417
|
|
413
418
|
# Is this query scoped to the default graph?
|
414
419
|
# @return [Boolean]
|
415
420
|
def default?
|
416
|
-
|
421
|
+
graph_name == false
|
417
422
|
end
|
418
423
|
|
419
424
|
# Is this query unscoped? This indicates that it can return results from
|
420
425
|
# either a named graph or the default graph.
|
421
426
|
# @return [Boolean]
|
422
427
|
def unnamed?
|
423
|
-
|
424
|
-
end
|
425
|
-
|
426
|
-
# Scope the query to named graphs matching value
|
427
|
-
# @param [RDF::IRI, RDF::Query::Variable] value
|
428
|
-
# @return [RDF::IRI, RDF::Query::Variable]
|
429
|
-
def graph_name=(value)
|
430
|
-
options[:graph_name] = value
|
431
|
-
end
|
432
|
-
|
433
|
-
# Scope of this query, if any
|
434
|
-
# @return [RDF::IRI, RDF::Query::Variable]
|
435
|
-
def graph_name
|
436
|
-
options[:graph_name]
|
428
|
+
graph_name.nil?
|
437
429
|
end
|
438
430
|
|
439
431
|
# Apply the graph name specified (or configured) to all patterns that have no graph name
|
440
432
|
# @param [RDF::IRI, RDF::Query::Variable] graph_name (self.graph_name)
|
441
|
-
def apply_graph_name(graph_name =
|
433
|
+
def apply_graph_name(graph_name = nil)
|
434
|
+
graph_name ||= self.graph_name
|
442
435
|
patterns.each {|pattern| pattern.graph_name = graph_name if pattern.graph_name.nil?} unless graph_name.nil?
|
443
436
|
end
|
444
437
|
|
@@ -515,8 +508,7 @@ module RDF
|
|
515
508
|
# @return [RDF::Query]
|
516
509
|
def dup
|
517
510
|
patterns = @patterns.map {|p| p.dup}
|
518
|
-
patterns
|
519
|
-
Query.new(*patterns)
|
511
|
+
Query.new(patterns, graph_name: graph_name, solutions: @solutions.dup, **options)
|
520
512
|
end
|
521
513
|
|
522
514
|
##
|