sparql-client 2.2.1 → 3.1.2
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 +5 -5
- data/README.md +115 -82
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/lib/sparql/client.rb +141 -75
- data/lib/sparql/client/query.rb +163 -67
- data/lib/sparql/client/repository.rb +16 -17
- data/lib/sparql/client/update.rb +37 -38
- data/lib/sparql/client/version.rb +2 -2
- metadata +36 -55
data/lib/sparql/client/query.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
|
-
|
1
|
+
require 'delegate'
|
2
|
+
|
3
|
+
class SPARQL::Client
|
2
4
|
##
|
3
5
|
# A SPARQL query builder.
|
4
6
|
#
|
@@ -10,19 +12,13 @@ module SPARQL; class Client
|
|
10
12
|
# The form of the query.
|
11
13
|
#
|
12
14
|
# @return [:select, :ask, :construct, :describe]
|
13
|
-
# @see
|
15
|
+
# @see https://www.w3.org/TR/sparql11-query/#QueryForms
|
14
16
|
attr_reader :form
|
15
17
|
|
16
18
|
##
|
17
19
|
# @return [Hash{Symbol => Object}]
|
18
20
|
attr_reader :options
|
19
21
|
|
20
|
-
##
|
21
|
-
# Values returned from previous query.
|
22
|
-
#
|
23
|
-
# @return [Array<[key, RDF::Value]>]
|
24
|
-
attr_reader :values
|
25
|
-
|
26
22
|
##
|
27
23
|
# Creates a boolean `ASK` query.
|
28
24
|
#
|
@@ -31,34 +27,33 @@ module SPARQL; class Client
|
|
31
27
|
#
|
32
28
|
# @param [Hash{Symbol => Object}] options (see {#initialize})
|
33
29
|
# @return [Query]
|
34
|
-
# @see
|
35
|
-
def self.ask(options
|
36
|
-
self.new(:ask, options)
|
30
|
+
# @see https://www.w3.org/TR/sparql11-query/#ask
|
31
|
+
def self.ask(**options)
|
32
|
+
self.new(:ask, **options)
|
37
33
|
end
|
38
34
|
|
39
35
|
##
|
40
36
|
# Creates a tuple `SELECT` query.
|
41
37
|
#
|
42
|
-
# @example SELECT * WHERE { ?s ?p ?o . }
|
38
|
+
# @example `SELECT * WHERE { ?s ?p ?o . }`
|
43
39
|
# Query.select.where([:s, :p, :o])
|
44
40
|
#
|
45
|
-
# @example SELECT ?s WHERE {?s ?p ?o .}
|
41
|
+
# @example `SELECT ?s WHERE {?s ?p ?o .}`
|
46
42
|
# Query.select(:s).where([:s, :p, :o])
|
47
43
|
#
|
48
|
-
# @example SELECT COUNT(?uri as ?c) WHERE {?uri a owl:Class}
|
44
|
+
# @example `SELECT COUNT(?uri as ?c) WHERE {?uri a owl:Class}`
|
49
45
|
# Query.select(count: {uri: :c}).where([:uri, RDF.type, RDF::OWL.Class])
|
50
46
|
#
|
51
47
|
# @param [Array<Symbol>] variables
|
52
48
|
# @return [Query]
|
53
49
|
#
|
54
|
-
# @overload self.select(*variables, options)
|
50
|
+
# @overload self.select(*variables, **options)
|
55
51
|
# @param [Array<Symbol>] variables
|
56
52
|
# @param [Hash{Symbol => Object}] options (see {#initialize})
|
57
53
|
# @return [Query]
|
58
|
-
# @see
|
59
|
-
def self.select(*variables)
|
60
|
-
options
|
61
|
-
self.new(:select, options).select(*variables)
|
54
|
+
# @see https://www.w3.org/TR/sparql11-query/#select
|
55
|
+
def self.select(*variables, **options)
|
56
|
+
self.new(:select, **options).select(*variables)
|
62
57
|
end
|
63
58
|
|
64
59
|
##
|
@@ -70,14 +65,13 @@ module SPARQL; class Client
|
|
70
65
|
# @param [Array<Symbol, RDF::URI>] variables
|
71
66
|
# @return [Query]
|
72
67
|
#
|
73
|
-
# @overload self.describe(*variables, options)
|
68
|
+
# @overload self.describe(*variables, **options)
|
74
69
|
# @param [Array<Symbol, RDF::URI>] variables
|
75
70
|
# @param [Hash{Symbol => Object}] options (see {#initialize})
|
76
71
|
# @return [Query]
|
77
|
-
# @see
|
78
|
-
def self.describe(*variables)
|
79
|
-
options
|
80
|
-
self.new(:describe, options).describe(*variables)
|
72
|
+
# @see https://www.w3.org/TR/sparql11-query/#describe
|
73
|
+
def self.describe(*variables, **options)
|
74
|
+
self.new(:describe, **options).describe(*variables)
|
81
75
|
end
|
82
76
|
|
83
77
|
##
|
@@ -89,19 +83,18 @@ module SPARQL; class Client
|
|
89
83
|
# @param [Array<RDF::Query::Pattern, Array>] patterns
|
90
84
|
# @return [Query]
|
91
85
|
#
|
92
|
-
# @overload self.construct(*variables, options)
|
86
|
+
# @overload self.construct(*variables, **options)
|
93
87
|
# @param [Array<RDF::Query::Pattern, Array>] patterns
|
94
88
|
# @param [Hash{Symbol => Object}] options (see {#initialize})
|
95
89
|
# @return [Query]
|
96
|
-
# @see
|
97
|
-
def self.construct(*patterns)
|
98
|
-
options
|
99
|
-
self.new(:construct, options).construct(*patterns) # FIXME
|
90
|
+
# @see https://www.w3.org/TR/sparql11-query/#construct
|
91
|
+
def self.construct(*patterns, **options)
|
92
|
+
self.new(:construct, **options).construct(*patterns) # FIXME
|
100
93
|
end
|
101
94
|
|
102
95
|
##
|
103
96
|
# @param [Symbol, #to_s] form
|
104
|
-
# @overload self.construct(*variables, options)
|
97
|
+
# @overload self.construct(*variables, **options)
|
105
98
|
# @param [Symbol, #to_s] form
|
106
99
|
# @param [Hash{Symbol => Object}] options (see {Client#initialize})
|
107
100
|
# @option options [Hash{Symbol => Symbol}] :count
|
@@ -110,10 +103,10 @@ module SPARQL; class Client
|
|
110
103
|
#
|
111
104
|
# @yield [query]
|
112
105
|
# @yieldparam [Query]
|
113
|
-
def initialize(form = :ask, options
|
106
|
+
def initialize(form = :ask, **options, &block)
|
114
107
|
@subqueries = []
|
115
108
|
@form = form.respond_to?(:to_sym) ? form.to_sym : form.to_s.to_sym
|
116
|
-
super([], options, &block)
|
109
|
+
super([], **options, &block)
|
117
110
|
end
|
118
111
|
|
119
112
|
##
|
@@ -121,27 +114,31 @@ module SPARQL; class Client
|
|
121
114
|
# query.ask.where([:s, :p, :o])
|
122
115
|
#
|
123
116
|
# @return [Query]
|
124
|
-
# @see
|
117
|
+
# @see https://www.w3.org/TR/sparql11-query/#ask
|
125
118
|
def ask
|
126
119
|
@form = :ask
|
127
120
|
self
|
128
121
|
end
|
129
122
|
|
130
123
|
##
|
131
|
-
# @example SELECT * WHERE { ?s ?p ?o . }
|
124
|
+
# @example `SELECT * WHERE { ?s ?p ?o . }`
|
132
125
|
# query.select.where([:s, :p, :o])
|
133
126
|
#
|
134
|
-
# @example SELECT ?s WHERE {?s ?p ?o .}
|
127
|
+
# @example `SELECT ?s WHERE {?s ?p ?o .}`
|
135
128
|
# query.select(:s).where([:s, :p, :o])
|
136
129
|
#
|
137
|
-
# @example SELECT COUNT(?uri as ?c) WHERE {?uri a owl:Class}
|
130
|
+
# @example `SELECT COUNT(?uri as ?c) WHERE {?uri a owl:Class}`
|
138
131
|
# query.select(count: {uri: :c}).where([:uri, RDF.type, RDF::OWL.Class])
|
139
132
|
#
|
140
|
-
# @param [Array<Symbol
|
133
|
+
# @param [Array<Symbol>, Hash{Symbol => RDF::Query::Variable}] variables
|
141
134
|
# @return [Query]
|
142
|
-
# @see
|
135
|
+
# @see https://www.w3.org/TR/sparql11-query/#select
|
143
136
|
def select(*variables)
|
144
|
-
@values = variables.
|
137
|
+
@values = if variables.length == 1 && variables.first.is_a?(Hash)
|
138
|
+
variables.to_a
|
139
|
+
else
|
140
|
+
variables.map { |var| [var, RDF::Query::Variable.new(var)] }
|
141
|
+
end
|
145
142
|
self
|
146
143
|
end
|
147
144
|
|
@@ -151,7 +148,7 @@ module SPARQL; class Client
|
|
151
148
|
#
|
152
149
|
# @param [Array<Symbol>] variables
|
153
150
|
# @return [Query]
|
154
|
-
# @see
|
151
|
+
# @see https://www.w3.org/TR/sparql11-query/#describe
|
155
152
|
def describe(*variables)
|
156
153
|
@values = variables.map { |var|
|
157
154
|
[var, var.is_a?(RDF::URI) ? var : RDF::Query::Variable.new(var)]
|
@@ -165,7 +162,7 @@ module SPARQL; class Client
|
|
165
162
|
#
|
166
163
|
# @param [Array<RDF::Query::Pattern, Array>] patterns
|
167
164
|
# @return [Query]
|
168
|
-
# @see
|
165
|
+
# @see https://www.w3.org/TR/sparql11-query/#construct
|
169
166
|
def construct(*patterns)
|
170
167
|
options[:template] = build_patterns(patterns)
|
171
168
|
self
|
@@ -177,7 +174,7 @@ module SPARQL; class Client
|
|
177
174
|
#
|
178
175
|
# @param [RDF::URI] uri
|
179
176
|
# @return [Query]
|
180
|
-
# @see
|
177
|
+
# @see https://www.w3.org/TR/sparql11-query/#specifyingDataset
|
181
178
|
def from(uri)
|
182
179
|
options[:from] = uri
|
183
180
|
self
|
@@ -210,7 +207,7 @@ module SPARQL; class Client
|
|
210
207
|
# Yield form with or without argument; without an argument, evaluates within the query.
|
211
208
|
# @yieldparam [SPARQL::Client::Query] query Actually a delegator to query. Methods other than `#select` are evaluated against `self`. For `#select`, a new Query is created, and the result added as a subquery.
|
212
209
|
# @return [Query]
|
213
|
-
# @see
|
210
|
+
# @see https://www.w3.org/TR/sparql11-query/#GraphPattern
|
214
211
|
def where(*patterns_queries, &block)
|
215
212
|
subqueries, patterns = patterns_queries.partition {|pq| pq.is_a? SPARQL::Client::Query}
|
216
213
|
@patterns += build_patterns(patterns)
|
@@ -246,11 +243,11 @@ module SPARQL; class Client
|
|
246
243
|
# query.select.where([:s, :p, :o]).order_by(:o, :p)
|
247
244
|
#
|
248
245
|
# @example SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o) DESC(?p)
|
249
|
-
# query.select.where([:s, :p, :o]).order_by(:
|
246
|
+
# query.select.where([:s, :p, :o]).order_by(o: :asc, p: :desc)
|
250
247
|
#
|
251
248
|
# @param [Array<Symbol, String>] variables
|
252
249
|
# @return [Query]
|
253
|
-
# @see
|
250
|
+
# @see https://www.w3.org/TR/sparql11-query/#modOrderBy
|
254
251
|
def order(*variables)
|
255
252
|
options[:order_by] = variables
|
256
253
|
self
|
@@ -265,7 +262,7 @@ module SPARQL; class Client
|
|
265
262
|
#
|
266
263
|
# @param [Array<Symbol, String>] var
|
267
264
|
# @return [Query]
|
268
|
-
# @see
|
265
|
+
# @see https://www.w3.org/TR/sparql11-query/#modOrderBy
|
269
266
|
def asc(var)
|
270
267
|
(options[:order_by] ||= []) << {var => :asc}
|
271
268
|
self
|
@@ -278,7 +275,7 @@ module SPARQL; class Client
|
|
278
275
|
#
|
279
276
|
# @param [Array<Symbol, String>] var
|
280
277
|
# @return [Query]
|
281
|
-
# @see
|
278
|
+
# @see https://www.w3.org/TR/sparql11-query/#modOrderBy
|
282
279
|
def desc(var)
|
283
280
|
(options[:order_by] ||= []) << {var => :desc}
|
284
281
|
self
|
@@ -290,7 +287,7 @@ module SPARQL; class Client
|
|
290
287
|
#
|
291
288
|
# @param [Array<Symbol, String>] variables
|
292
289
|
# @return [Query]
|
293
|
-
# @see
|
290
|
+
# @see https://www.w3.org/TR/sparql11-query/#groupby
|
294
291
|
def group(*variables)
|
295
292
|
options[:group_by] = variables
|
296
293
|
self
|
@@ -303,7 +300,7 @@ module SPARQL; class Client
|
|
303
300
|
# query.select(:s).distinct.where([:s, :p, :o])
|
304
301
|
#
|
305
302
|
# @return [Query]
|
306
|
-
# @see
|
303
|
+
# @see https://www.w3.org/TR/sparql11-query/#modDuplicates
|
307
304
|
def distinct(state = true)
|
308
305
|
options[:distinct] = state
|
309
306
|
self
|
@@ -314,7 +311,7 @@ module SPARQL; class Client
|
|
314
311
|
# query.select(:s).reduced.where([:s, :p, :o])
|
315
312
|
#
|
316
313
|
# @return [Query]
|
317
|
-
# @see
|
314
|
+
# @see https://www.w3.org/TR/sparql11-query/#modDuplicates
|
318
315
|
def reduced(state = true)
|
319
316
|
options[:reduced] = state
|
320
317
|
self
|
@@ -325,7 +322,7 @@ module SPARQL; class Client
|
|
325
322
|
# query.select.graph(:g).where([:s, :p, :o])
|
326
323
|
# @param [RDF::Value] graph_uri_or_var
|
327
324
|
# @return [Query]
|
328
|
-
# @see
|
325
|
+
# @see https://www.w3.org/TR/sparql11-query/#queryDataset
|
329
326
|
def graph(graph_uri_or_var)
|
330
327
|
options[:graph] = case graph_uri_or_var
|
331
328
|
when Symbol then RDF::Query::Variable.new(graph_uri_or_var)
|
@@ -342,7 +339,7 @@ module SPARQL; class Client
|
|
342
339
|
#
|
343
340
|
# @param [Integer, #to_i] start
|
344
341
|
# @return [Query]
|
345
|
-
# @see
|
342
|
+
# @see https://www.w3.org/TR/sparql11-query/#modOffset
|
346
343
|
def offset(start)
|
347
344
|
slice(start, nil)
|
348
345
|
end
|
@@ -353,7 +350,7 @@ module SPARQL; class Client
|
|
353
350
|
#
|
354
351
|
# @param [Integer, #to_i] length
|
355
352
|
# @return [Query]
|
356
|
-
# @see
|
353
|
+
# @see https://www.w3.org/TR/sparql11-query/#modResultLimit
|
357
354
|
def limit(length)
|
358
355
|
slice(nil, length)
|
359
356
|
end
|
@@ -372,16 +369,38 @@ module SPARQL; class Client
|
|
372
369
|
end
|
373
370
|
|
374
371
|
##
|
375
|
-
# @
|
376
|
-
#
|
377
|
-
#
|
378
|
-
#
|
379
|
-
#
|
372
|
+
# @overload prefix(prefix: uri)
|
373
|
+
# @example PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT * WHERE \{ ?s ?p ?o . \}
|
374
|
+
# query.select.
|
375
|
+
# prefix(dc: RDF::URI("http://purl.org/dc/elements/1.1/")).
|
376
|
+
# prefix(foaf: RDF::URI("http://xmlns.com/foaf/0.1/")).
|
377
|
+
# where([:s, :p, :o])
|
380
378
|
#
|
381
|
-
#
|
382
|
-
#
|
383
|
-
|
384
|
-
|
379
|
+
# @param [RDF::URI] uri
|
380
|
+
# @param [Symbol, String] prefix
|
381
|
+
# @return [Query]
|
382
|
+
#
|
383
|
+
# @overload prefix(string)
|
384
|
+
# @example PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT * WHERE \{ ?s ?p ?o . \}
|
385
|
+
# query.select.
|
386
|
+
# prefix("dc: <http://purl.org/dc/elements/1.1/>").
|
387
|
+
# prefix("foaf: <http://xmlns.com/foaf/0.1/>").
|
388
|
+
# where([:s, :p, :o])
|
389
|
+
#
|
390
|
+
# @param [string] string
|
391
|
+
# @return [Query]
|
392
|
+
# @see https://www.w3.org/TR/sparql11-query/#prefNames
|
393
|
+
def prefix(val)
|
394
|
+
options[:prefixes] ||= []
|
395
|
+
if val.kind_of? String
|
396
|
+
options[:prefixes] << val
|
397
|
+
elsif val.kind_of? Hash
|
398
|
+
val.each do |k, v|
|
399
|
+
options[:prefixes] << "#{k}: <#{v}>"
|
400
|
+
end
|
401
|
+
else
|
402
|
+
raise ArgumentError, "prefix must be a kind of String or a Hash"
|
403
|
+
end
|
385
404
|
self
|
386
405
|
end
|
387
406
|
|
@@ -403,7 +422,7 @@ module SPARQL; class Client
|
|
403
422
|
# Yield form with or without argument; without an argument, evaluates within the query.
|
404
423
|
# @yieldparam [SPARQL::Client::Query] query used for creating filters on the optional patterns.
|
405
424
|
# @return [Query]
|
406
|
-
# @see
|
425
|
+
# @see https://www.w3.org/TR/sparql11-query/#optionals
|
407
426
|
def optional(*patterns, &block)
|
408
427
|
(options[:optionals] ||= []) << build_patterns(patterns)
|
409
428
|
|
@@ -449,7 +468,7 @@ module SPARQL; class Client
|
|
449
468
|
# Yield form with or without argument; without an argument, evaluates within the query.
|
450
469
|
# @yieldparam [SPARQL::Client::Query] query used for adding select clauses.
|
451
470
|
# @return [Query]
|
452
|
-
# @see
|
471
|
+
# @see https://www.w3.org/TR/sparql11-query/#optionals
|
453
472
|
def union(*patterns, &block)
|
454
473
|
options[:unions] ||= []
|
455
474
|
|
@@ -502,7 +521,7 @@ module SPARQL; class Client
|
|
502
521
|
# Yield form with or without argument; without an argument, evaluates within the query.
|
503
522
|
# @yieldparam [SPARQL::Client::Query] query used for adding select clauses.
|
504
523
|
# @return [Query]
|
505
|
-
# @see
|
524
|
+
# @see https://www.w3.org/TR/sparql11-query/#optionals
|
506
525
|
def minus(*patterns, &block)
|
507
526
|
options[:minuses] ||= []
|
508
527
|
|
@@ -528,6 +547,71 @@ module SPARQL; class Client
|
|
528
547
|
self
|
529
548
|
end
|
530
549
|
|
550
|
+
##
|
551
|
+
# Specify inline data for a query
|
552
|
+
#
|
553
|
+
# @overload values
|
554
|
+
# Values returned from previous query.
|
555
|
+
#
|
556
|
+
# @return [Array<Array(key, RDF::Value)>]
|
557
|
+
#
|
558
|
+
# @overload values(vars, *data)
|
559
|
+
# @example single variable with multiple values
|
560
|
+
# query.select
|
561
|
+
# .where([:s, RDF::URI('http://purl.org/dc/terms/title'), :title])
|
562
|
+
# .values(:title, "This title", "Another title")
|
563
|
+
#
|
564
|
+
# @example multiple variables with multiple values
|
565
|
+
# query.select
|
566
|
+
# .where([:s, RDF::URI('http://purl.org/dc/terms/title'), :title],
|
567
|
+
# [:s, RDF.type, :type])
|
568
|
+
# .values([:type, :title],
|
569
|
+
# [RDF::URI('http://pcdm.org/models#Object'), "This title"],
|
570
|
+
# [RDF::URI('http://pcdm.org/models#Collection', 'Another title'])
|
571
|
+
#
|
572
|
+
# @example multiple variables with UNDEF
|
573
|
+
# query.select
|
574
|
+
# .where([:s, RDF::URI('http://purl.org/dc/terms/title'), :title],
|
575
|
+
# [:s, RDF.type, :type])
|
576
|
+
# .values([:type, :title],
|
577
|
+
# [nil "This title"],
|
578
|
+
# [RDF::URI('http://pcdm.org/models#Collection', nil])
|
579
|
+
#
|
580
|
+
# @param [Symbol, Array<Symbol>] vars
|
581
|
+
# @param [Array<RDF::Term, String, nil>] *data
|
582
|
+
# @return [Query]
|
583
|
+
def values(*args)
|
584
|
+
return @values if args.empty?
|
585
|
+
vars, *data = *args
|
586
|
+
vars = Array(vars).map {|var| RDF::Query::Variable.new(var)}
|
587
|
+
if vars.length == 1
|
588
|
+
# data may be a in array form or simple form
|
589
|
+
if data.any? {|d| d.is_a?(Array)} && !data.all? {|d| d.is_a?(Array)}
|
590
|
+
raise ArgumentError, "values data must all be in array form or all simple"
|
591
|
+
end
|
592
|
+
data = data.map {|d| Array(d)}
|
593
|
+
end
|
594
|
+
|
595
|
+
# Each data value must be an array with the same number of entries as vars
|
596
|
+
unless data.all? {|d| d.is_a?(Array) && d.all? {|dd| dd.is_a?(RDF::Value) || dd.is_a?(String) || dd.nil?}}
|
597
|
+
raise ArgumentError, "values data must each be an array of terms, strings, or nil"
|
598
|
+
end
|
599
|
+
|
600
|
+
# Turn strings into Literals
|
601
|
+
data = data.map do |d|
|
602
|
+
d.map do |nil_literal_or_term|
|
603
|
+
case nil_literal_or_term
|
604
|
+
when nil then nil
|
605
|
+
when String then RDF::Literal(nil_literal_or_term)
|
606
|
+
when RDF::Value then nil_literal_or_term
|
607
|
+
else raise ArgumentError
|
608
|
+
end
|
609
|
+
end
|
610
|
+
end
|
611
|
+
options[:values] = [vars, *data]
|
612
|
+
self
|
613
|
+
end
|
614
|
+
|
531
615
|
##
|
532
616
|
# @return expects_statements?
|
533
617
|
def expects_statements?
|
@@ -646,7 +730,7 @@ module SPARQL; class Client
|
|
646
730
|
buffer << 'ORDER BY'
|
647
731
|
options[:order_by].map { |elem|
|
648
732
|
case elem
|
649
|
-
# .order_by({ :
|
733
|
+
# .order_by({ var1: :asc, var2: :desc})
|
650
734
|
when Hash
|
651
735
|
elem.each { |key, val|
|
652
736
|
# check provided values
|
@@ -712,6 +796,18 @@ module SPARQL; class Client
|
|
712
796
|
if options[:filters]
|
713
797
|
buffer += options[:filters].map(&:to_s)
|
714
798
|
end
|
799
|
+
if options[:values]
|
800
|
+
vars = options[:values].first.map {|var| SPARQL::Client.serialize_value(var)}
|
801
|
+
buffer << "VALUES (#{vars.join(' ')}) {"
|
802
|
+
options[:values][1..-1].each do |data_block_value|
|
803
|
+
buffer << '('
|
804
|
+
buffer << data_block_value.map do |value|
|
805
|
+
value.nil? ? 'UNDEF' : SPARQL::Client.serialize_value(value)
|
806
|
+
end.join(' ')
|
807
|
+
buffer << ')'
|
808
|
+
end
|
809
|
+
buffer << '}'
|
810
|
+
end
|
715
811
|
if options[:graph]
|
716
812
|
buffer << '}' # GRAPH
|
717
813
|
end
|
@@ -752,4 +848,4 @@ module SPARQL; class Client
|
|
752
848
|
end
|
753
849
|
end
|
754
850
|
end
|
755
|
-
end
|
851
|
+
end
|