sparql-client 3.0.1 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +58 -47
- data/UNLICENSE +1 -1
- data/VERSION +1 -1
- data/lib/sparql/client/query.rb +55 -52
- data/lib/sparql/client/repository.rb +14 -14
- data/lib/sparql/client/update.rb +37 -38
- data/lib/sparql/client.rb +111 -69
- metadata +30 -31
data/lib/sparql/client/update.rb
CHANGED
@@ -12,12 +12,12 @@ class SPARQL::Client
|
|
12
12
|
# insert_data(data)
|
13
13
|
#
|
14
14
|
# @example INSERT DATA \{ GRAPH <http://example.org/> \{\}\}
|
15
|
-
# insert_data(RDF::Graph.new, :
|
15
|
+
# insert_data(RDF::Graph.new, graph: 'http://example.org/')
|
16
16
|
# insert_data(RDF::Graph.new).graph('http://example.org/')
|
17
17
|
#
|
18
18
|
# @param (see InsertData#initialize)
|
19
|
-
def self.insert_data(*arguments)
|
20
|
-
InsertData.new(*arguments)
|
19
|
+
def self.insert_data(*arguments, **options)
|
20
|
+
InsertData.new(*arguments, **options)
|
21
21
|
end
|
22
22
|
|
23
23
|
##
|
@@ -30,12 +30,12 @@ class SPARQL::Client
|
|
30
30
|
# delete_data(data)
|
31
31
|
#
|
32
32
|
# @example DELETE DATA \{ GRAPH <http://example.org/> \{\}\}
|
33
|
-
# delete_data(RDF::Graph.new, :
|
33
|
+
# delete_data(RDF::Graph.new, graph: 'http://example.org/')
|
34
34
|
# delete_data(RDF::Graph.new).graph('http://example.org/')
|
35
35
|
#
|
36
36
|
# @param (see DeleteData#initialize)
|
37
|
-
def self.delete_data(*arguments)
|
38
|
-
DeleteData.new(*arguments)
|
37
|
+
def self.delete_data(*arguments, **options)
|
38
|
+
DeleteData.new(*arguments, **options)
|
39
39
|
end
|
40
40
|
|
41
41
|
##
|
@@ -53,8 +53,8 @@ class SPARQL::Client
|
|
53
53
|
# load(RDF::URI(http://example.org/data.rdf), into: RDF::URI(http://example.org/data.rdf))
|
54
54
|
#
|
55
55
|
# @param (see Load#initialize)
|
56
|
-
def self.load(*arguments)
|
57
|
-
Load.new(*arguments)
|
56
|
+
def self.load(*arguments, **options)
|
57
|
+
Load.new(*arguments, **options)
|
58
58
|
end
|
59
59
|
|
60
60
|
##
|
@@ -81,8 +81,8 @@ class SPARQL::Client
|
|
81
81
|
# clear(:all, silent: true)
|
82
82
|
#
|
83
83
|
# @param (see Clear#initialize)
|
84
|
-
def self.clear(*arguments)
|
85
|
-
Clear.new(*arguments)
|
84
|
+
def self.clear(*arguments, **options)
|
85
|
+
Clear.new(*arguments, **options)
|
86
86
|
end
|
87
87
|
|
88
88
|
##
|
@@ -96,8 +96,8 @@ class SPARQL::Client
|
|
96
96
|
# create(RDF::URI(http://example.org/data.rdf), silent: true)
|
97
97
|
#
|
98
98
|
# @param (see Create#initialize)
|
99
|
-
def self.create(*arguments)
|
100
|
-
Create.new(*arguments)
|
99
|
+
def self.create(*arguments, **options)
|
100
|
+
Create.new(*arguments, **options)
|
101
101
|
end
|
102
102
|
|
103
103
|
##
|
@@ -124,15 +124,15 @@ class SPARQL::Client
|
|
124
124
|
# drop(:all, silent: true)
|
125
125
|
#
|
126
126
|
# @param (see Drop#initialize)
|
127
|
-
def self.drop(*arguments)
|
128
|
-
Drop.new(*arguments)
|
127
|
+
def self.drop(*arguments, **options)
|
128
|
+
Drop.new(*arguments, **options)
|
129
129
|
end
|
130
130
|
|
131
131
|
class Operation
|
132
132
|
attr_reader :options
|
133
133
|
|
134
|
-
def initialize(*arguments)
|
135
|
-
@options =
|
134
|
+
def initialize(*arguments, **options)
|
135
|
+
@options = options.dup
|
136
136
|
unless arguments.empty?
|
137
137
|
send(arguments.shift, *arguments)
|
138
138
|
end
|
@@ -155,7 +155,7 @@ class SPARQL::Client
|
|
155
155
|
end
|
156
156
|
|
157
157
|
##
|
158
|
-
# @see
|
158
|
+
# @see https://www.w3.org/TR/sparql11-update/#insertData
|
159
159
|
class InsertData < Operation
|
160
160
|
# @return [RDF::Enumerable]
|
161
161
|
attr_reader :data
|
@@ -171,9 +171,9 @@ class SPARQL::Client
|
|
171
171
|
#
|
172
172
|
# @param [Array<RDF::Statement>, RDF::Enumerable] data
|
173
173
|
# @param [Hash{Symbol => Object}] options
|
174
|
-
def initialize(data, options
|
174
|
+
def initialize(data, **options)
|
175
175
|
@data = data
|
176
|
-
super(options)
|
176
|
+
super(**options)
|
177
177
|
end
|
178
178
|
|
179
179
|
##
|
@@ -205,7 +205,7 @@ class SPARQL::Client
|
|
205
205
|
end
|
206
206
|
|
207
207
|
##
|
208
|
-
# @see
|
208
|
+
# @see https://www.w3.org/TR/sparql11-update/#deleteData
|
209
209
|
class DeleteData < Operation
|
210
210
|
# @return [RDF::Enumerable]
|
211
211
|
attr_reader :data
|
@@ -221,9 +221,9 @@ class SPARQL::Client
|
|
221
221
|
#
|
222
222
|
# @param [Array<RDF::Statement>, RDF::Enumerable] data
|
223
223
|
# @param [Hash{Symbol => Object}] options
|
224
|
-
def initialize(data, options
|
224
|
+
def initialize(data, **options)
|
225
225
|
@data = data
|
226
|
-
super(options)
|
226
|
+
super(**options)
|
227
227
|
end
|
228
228
|
|
229
229
|
##
|
@@ -247,17 +247,17 @@ class SPARQL::Client
|
|
247
247
|
end
|
248
248
|
|
249
249
|
##
|
250
|
-
# @see
|
250
|
+
# @see https://www.w3.org/TR/sparql11-update/#deleteInsert
|
251
251
|
class DeleteInsert < Operation
|
252
252
|
attr_reader :insert_graph
|
253
253
|
attr_reader :delete_graph
|
254
254
|
attr_reader :where_graph
|
255
255
|
|
256
|
-
def initialize(_delete_graph, _insert_graph = nil, _where_graph = nil, options
|
256
|
+
def initialize(_delete_graph, _insert_graph = nil, _where_graph = nil, **options)
|
257
257
|
@delete_graph = _delete_graph
|
258
258
|
@insert_graph = _insert_graph
|
259
259
|
@where_graph = _where_graph
|
260
|
-
super(options)
|
260
|
+
super(**options)
|
261
261
|
end
|
262
262
|
|
263
263
|
##
|
@@ -301,7 +301,7 @@ class SPARQL::Client
|
|
301
301
|
end
|
302
302
|
|
303
303
|
##
|
304
|
-
# @see
|
304
|
+
# @see https://www.w3.org/TR/sparql11-update/#load
|
305
305
|
class Load < Operation
|
306
306
|
attr_reader :from
|
307
307
|
attr_reader :into
|
@@ -324,11 +324,10 @@ class SPARQL::Client
|
|
324
324
|
# @param [Hash{Symbol => Object}] options
|
325
325
|
# @option [RDF::URI] :into
|
326
326
|
# @option [Boolean] :silent
|
327
|
-
def initialize(from, options
|
328
|
-
options = options.dup
|
327
|
+
def initialize(from, into: nil,**options)
|
329
328
|
@from = RDF::URI(from)
|
330
|
-
@into = RDF::URI(
|
331
|
-
super(options)
|
329
|
+
@into = RDF::URI(into) if into
|
330
|
+
super(**options)
|
332
331
|
end
|
333
332
|
|
334
333
|
##
|
@@ -351,7 +350,7 @@ class SPARQL::Client
|
|
351
350
|
end
|
352
351
|
|
353
352
|
##
|
354
|
-
# @see
|
353
|
+
# @see https://www.w3.org/TR/sparql11-update/#clear
|
355
354
|
class Clear < Operation
|
356
355
|
attr_reader :uri
|
357
356
|
|
@@ -415,14 +414,14 @@ class SPARQL::Client
|
|
415
414
|
end
|
416
415
|
|
417
416
|
##
|
418
|
-
# @see
|
417
|
+
# @see https://www.w3.org/TR/sparql11-update/#create
|
419
418
|
class Create < Operation
|
420
419
|
attr_reader :uri
|
421
420
|
|
422
421
|
# @param [Hash{Symbol => Object}] options
|
423
|
-
def initialize(uri, options
|
422
|
+
def initialize(uri, **options)
|
424
423
|
@uri = RDF::URI(uri)
|
425
|
-
super(options)
|
424
|
+
super(**options)
|
426
425
|
end
|
427
426
|
|
428
427
|
def to_s
|
@@ -434,7 +433,7 @@ class SPARQL::Client
|
|
434
433
|
end
|
435
434
|
|
436
435
|
##
|
437
|
-
# @see
|
436
|
+
# @see https://www.w3.org/TR/sparql11-update/#drop
|
438
437
|
class Drop < Clear
|
439
438
|
def to_s
|
440
439
|
query_text = 'DROP '
|
@@ -451,7 +450,7 @@ class SPARQL::Client
|
|
451
450
|
end
|
452
451
|
|
453
452
|
##
|
454
|
-
# @see
|
453
|
+
# @see https://www.w3.org/TR/sparql11-update/#copy
|
455
454
|
class Copy < Operation
|
456
455
|
def to_s
|
457
456
|
# TODO
|
@@ -459,7 +458,7 @@ class SPARQL::Client
|
|
459
458
|
end
|
460
459
|
|
461
460
|
##
|
462
|
-
# @see
|
461
|
+
# @see https://www.w3.org/TR/sparql11-update/#move
|
463
462
|
class Move < Operation
|
464
463
|
def to_s
|
465
464
|
# TODO
|
@@ -467,7 +466,7 @@ class SPARQL::Client
|
|
467
466
|
end
|
468
467
|
|
469
468
|
##
|
470
|
-
# @see
|
469
|
+
# @see https://www.w3.org/TR/sparql11-update/#add
|
471
470
|
class Add < Operation
|
472
471
|
def to_s
|
473
472
|
# TODO
|
data/lib/sparql/client.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
require 'net/http/persistent' # @see
|
2
|
-
require 'rdf' # @see
|
3
|
-
require 'rdf/ntriples' # @see
|
1
|
+
require 'net/http/persistent' # @see https://rubygems.org/gems/net-http-persistent
|
2
|
+
require 'rdf' # @see https://rubygems.org/gems/rdf
|
3
|
+
require 'rdf/ntriples' # @see https://rubygems.org/gems/rdf
|
4
4
|
begin
|
5
5
|
require 'nokogiri'
|
6
6
|
rescue LoadError
|
@@ -11,10 +11,10 @@ module SPARQL
|
|
11
11
|
##
|
12
12
|
# A SPARQL 1.0/1.1 client for RDF.rb.
|
13
13
|
#
|
14
|
-
# @see
|
15
|
-
# @see
|
16
|
-
# @see
|
17
|
-
# @see
|
14
|
+
# @see https://www.w3.org/TR/sparql11-query/
|
15
|
+
# @see https://www.w3.org/TR/sparql11-protocol/
|
16
|
+
# @see https://www.w3.org/TR/sparql11-results-json/
|
17
|
+
# @see https://www.w3.org/TR/sparql11-results-csv-tsv/
|
18
18
|
class Client
|
19
19
|
autoload :Query, 'sparql/client/query'
|
20
20
|
autoload :Repository, 'sparql/client/repository'
|
@@ -86,8 +86,13 @@ module SPARQL
|
|
86
86
|
# @option options [Symbol] :method (DEFAULT_METHOD)
|
87
87
|
# @option options [Number] :protocol (DEFAULT_PROTOCOL)
|
88
88
|
# @option options [Hash] :headers
|
89
|
+
# HTTP Request headers
|
90
|
+
#
|
91
|
+
# Defaults `Accept` header based on available reader content types if triples are expected and to SPARQL result types otherwise, to allow for content negotiation based on available readers.
|
92
|
+
#
|
93
|
+
# Defaults `User-Agent` header, unless one is specified.
|
89
94
|
# @option options [Hash] :read_timeout
|
90
|
-
def initialize(url, options
|
95
|
+
def initialize(url, **options, &block)
|
91
96
|
case url
|
92
97
|
when RDF::Queryable
|
93
98
|
@url, @options = url, options.dup
|
@@ -95,6 +100,9 @@ module SPARQL
|
|
95
100
|
@url, @options = RDF::URI.new(url.to_s), options.dup
|
96
101
|
@headers = @options.delete(:headers) || {}
|
97
102
|
@http = http_klass(@url.scheme)
|
103
|
+
|
104
|
+
# Close the http connection when object is deallocated
|
105
|
+
ObjectSpace.define_finalizer(self, self.class.finalize(@http))
|
98
106
|
end
|
99
107
|
|
100
108
|
if block_given?
|
@@ -105,13 +113,30 @@ module SPARQL
|
|
105
113
|
end
|
106
114
|
end
|
107
115
|
|
116
|
+
# Close the http connection when object is deallocated
|
117
|
+
def self.finalize(klass)
|
118
|
+
proc do
|
119
|
+
klass.shutdown if klass.respond_to?(:shutdown)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
##
|
124
|
+
# Closes a client instance by finishing the connection.
|
125
|
+
# The client is unavailable for any further data operations; an IOError is raised if such an attempt is made. I/O streams are automatically closed when they are claimed by the garbage collector.
|
126
|
+
# @return [void] `self`
|
127
|
+
def close
|
128
|
+
@http.shutdown if @http
|
129
|
+
@http = nil
|
130
|
+
self
|
131
|
+
end
|
132
|
+
|
108
133
|
##
|
109
134
|
# Executes a boolean `ASK` query.
|
110
135
|
#
|
111
136
|
# @param (see Query.ask)
|
112
137
|
# @return [Query]
|
113
|
-
def ask(*args)
|
114
|
-
call_query_method(:ask, *args)
|
138
|
+
def ask(*args, **options)
|
139
|
+
call_query_method(:ask, *args, **options)
|
115
140
|
end
|
116
141
|
|
117
142
|
##
|
@@ -119,8 +144,8 @@ module SPARQL
|
|
119
144
|
#
|
120
145
|
# @param (see Query.select)
|
121
146
|
# @return [Query]
|
122
|
-
def select(*args)
|
123
|
-
call_query_method(:select, *args)
|
147
|
+
def select(*args, **options)
|
148
|
+
call_query_method(:select, *args, **options)
|
124
149
|
end
|
125
150
|
|
126
151
|
##
|
@@ -128,8 +153,8 @@ module SPARQL
|
|
128
153
|
#
|
129
154
|
# @param (see Query.describe)
|
130
155
|
# @return [Query]
|
131
|
-
def describe(*args)
|
132
|
-
call_query_method(:describe, *args)
|
156
|
+
def describe(*args, **options)
|
157
|
+
call_query_method(:describe, *args, **options)
|
133
158
|
end
|
134
159
|
|
135
160
|
##
|
@@ -137,8 +162,8 @@ module SPARQL
|
|
137
162
|
#
|
138
163
|
# @param (see Query.construct)
|
139
164
|
# @return [Query]
|
140
|
-
def construct(*args)
|
141
|
-
call_query_method(:construct, *args)
|
165
|
+
def construct(*args, **options)
|
166
|
+
call_query_method(:construct, *args, **options)
|
142
167
|
end
|
143
168
|
|
144
169
|
##
|
@@ -161,15 +186,15 @@ module SPARQL
|
|
161
186
|
# client.insert_data(data)
|
162
187
|
#
|
163
188
|
# @example Inserting data into a named graph
|
164
|
-
# client.insert_data(data, :
|
189
|
+
# client.insert_data(data, graph: "http://example.org/")
|
165
190
|
#
|
166
191
|
# @param [RDF::Enumerable] data
|
167
192
|
# @param [Hash{Symbol => Object}] options
|
168
193
|
# @option options [RDF::URI, String] :graph
|
169
194
|
# @return [void] `self`
|
170
|
-
# @see
|
171
|
-
def insert_data(data, options
|
172
|
-
self.update(Update::InsertData.new(data, options))
|
195
|
+
# @see https://www.w3.org/TR/sparql11-update/#insertData
|
196
|
+
def insert_data(data, **options)
|
197
|
+
self.update(Update::InsertData.new(data, **options))
|
173
198
|
end
|
174
199
|
|
175
200
|
##
|
@@ -182,15 +207,15 @@ module SPARQL
|
|
182
207
|
# client.delete_data(data)
|
183
208
|
#
|
184
209
|
# @example Deleting data from a named graph
|
185
|
-
# client.delete_data(data, :
|
210
|
+
# client.delete_data(data, graph: "http://example.org/")
|
186
211
|
#
|
187
212
|
# @param [RDF::Enumerable] data
|
188
213
|
# @param [Hash{Symbol => Object}] options
|
189
214
|
# @option options [RDF::URI, String] :graph
|
190
215
|
# @return [void] `self`
|
191
|
-
# @see
|
192
|
-
def delete_data(data, options
|
193
|
-
self.update(Update::DeleteData.new(data, options))
|
216
|
+
# @see https://www.w3.org/TR/sparql11-update/#deleteData
|
217
|
+
def delete_data(data, **options)
|
218
|
+
self.update(Update::DeleteData.new(data, **options))
|
194
219
|
end
|
195
220
|
|
196
221
|
##
|
@@ -204,9 +229,9 @@ module SPARQL
|
|
204
229
|
# @param [Hash{Symbol => Object}] options
|
205
230
|
# @option options [RDF::URI, String] :graph
|
206
231
|
# @return [void] `self`
|
207
|
-
# @see
|
208
|
-
def delete_insert(delete_graph, insert_graph = nil, where_graph = nil, options
|
209
|
-
self.update(Update::DeleteInsert.new(delete_graph, insert_graph, where_graph, options))
|
232
|
+
# @see https://www.w3.org/TR/sparql11-update/#deleteInsert
|
233
|
+
def delete_insert(delete_graph, insert_graph = nil, where_graph = nil, **options)
|
234
|
+
self.update(Update::DeleteInsert.new(delete_graph, insert_graph, where_graph, **options))
|
210
235
|
end
|
211
236
|
|
212
237
|
##
|
@@ -221,9 +246,9 @@ module SPARQL
|
|
221
246
|
# @param [Hash{Symbol => Object}] options
|
222
247
|
# @option options [Boolean] :silent
|
223
248
|
# @return [void] `self`
|
224
|
-
# @see
|
225
|
-
def clear_graph(graph_uri, options
|
226
|
-
self.clear(:graph, graph_uri, options)
|
249
|
+
# @see https://www.w3.org/TR/sparql11-update/#clear
|
250
|
+
def clear_graph(graph_uri, **options)
|
251
|
+
self.clear(:graph, graph_uri, **options)
|
227
252
|
end
|
228
253
|
|
229
254
|
##
|
@@ -249,23 +274,23 @@ module SPARQL
|
|
249
274
|
# @option options [Boolean] :silent
|
250
275
|
# @return [void] `self`
|
251
276
|
#
|
252
|
-
# @overload clear(what, *arguments, options
|
277
|
+
# @overload clear(what, *arguments, **options)
|
253
278
|
# @param [Symbol, #to_sym] what
|
254
279
|
# @param [Array] arguments splat of other arguments to {Update::Clear}.
|
255
280
|
# @param [Hash{Symbol => Object}] options
|
256
281
|
# @option options [Boolean] :silent
|
257
282
|
# @return [void] `self`
|
258
283
|
#
|
259
|
-
# @see
|
284
|
+
# @see https://www.w3.org/TR/sparql11-update/#clear
|
260
285
|
def clear(what, *arguments)
|
261
286
|
self.update(Update::Clear.new(what, *arguments))
|
262
287
|
end
|
263
288
|
|
264
289
|
##
|
265
290
|
# @private
|
266
|
-
def call_query_method(meth, *args)
|
291
|
+
def call_query_method(meth, *args, **options)
|
267
292
|
client = self
|
268
|
-
result = Query.send(meth, *args)
|
293
|
+
result = Query.send(meth, *args, **options)
|
269
294
|
(class << result; self; end).send(:define_method, :execute) do
|
270
295
|
client.query(self)
|
271
296
|
end
|
@@ -288,21 +313,22 @@ module SPARQL
|
|
288
313
|
# @option options [String] :content_type
|
289
314
|
# @option options [Hash] :headers
|
290
315
|
# @return [Array<RDF::Query::Solution>]
|
291
|
-
# @
|
292
|
-
|
316
|
+
# @raise [IOError] if connection is closed
|
317
|
+
# @see https://www.w3.org/TR/sparql11-protocol/#query-operation
|
318
|
+
def query(query, **options)
|
293
319
|
@op = :query
|
294
320
|
@alt_endpoint = options[:endpoint]
|
295
321
|
case @url
|
296
322
|
when RDF::Queryable
|
297
323
|
require 'sparql' unless defined?(::SPARQL::Grammar)
|
298
324
|
begin
|
299
|
-
SPARQL.execute(query, @url, options)
|
325
|
+
SPARQL.execute(query, @url, optimize: true, **options)
|
300
326
|
rescue SPARQL::MalformedQuery
|
301
327
|
$stderr.puts "error running #{query}: #{$!}"
|
302
328
|
raise
|
303
329
|
end
|
304
330
|
else
|
305
|
-
parse_response(response(query, options), options)
|
331
|
+
parse_response(response(query, **options), **options)
|
306
332
|
end
|
307
333
|
end
|
308
334
|
|
@@ -315,16 +341,17 @@ module SPARQL
|
|
315
341
|
# @option options [String] :content_type
|
316
342
|
# @option options [Hash] :headers
|
317
343
|
# @return [void] `self`
|
318
|
-
# @
|
319
|
-
|
344
|
+
# @raise [IOError] if connection is closed
|
345
|
+
# @see https://www.w3.org/TR/sparql11-protocol/#update-operation
|
346
|
+
def update(query, **options)
|
320
347
|
@op = :update
|
321
348
|
@alt_endpoint = options[:endpoint]
|
322
349
|
case @url
|
323
350
|
when RDF::Queryable
|
324
351
|
require 'sparql' unless defined?(::SPARQL::Grammar)
|
325
|
-
SPARQL.execute(query, @url,
|
352
|
+
SPARQL.execute(query, @url, update: true, optimize: true, **options)
|
326
353
|
else
|
327
|
-
response(query, options)
|
354
|
+
response(query, **options)
|
328
355
|
end
|
329
356
|
self
|
330
357
|
end
|
@@ -338,8 +365,9 @@ module SPARQL
|
|
338
365
|
# @option options [String] :content_type
|
339
366
|
# @option options [Hash] :headers
|
340
367
|
# @return [String]
|
341
|
-
|
342
|
-
|
368
|
+
# @raise [IOError] if connection is closed
|
369
|
+
def response(query, **options)
|
370
|
+
headers = options[:headers] || @headers
|
343
371
|
headers['Accept'] = options[:content_type] if options[:content_type]
|
344
372
|
request(query, headers) do |response|
|
345
373
|
case response
|
@@ -359,7 +387,7 @@ module SPARQL
|
|
359
387
|
# @param [Net::HTTPSuccess] response
|
360
388
|
# @param [Hash{Symbol => Object}] options
|
361
389
|
# @return [Object]
|
362
|
-
def parse_response(response, options
|
390
|
+
def parse_response(response, **options)
|
363
391
|
case options[:content_type] || response.content_type
|
364
392
|
when NilClass
|
365
393
|
response.body
|
@@ -374,14 +402,14 @@ module SPARQL
|
|
374
402
|
when RESULT_TSV
|
375
403
|
self.class.parse_tsv_bindings(response.body, nodes)
|
376
404
|
else
|
377
|
-
parse_rdf_serialization(response, options)
|
405
|
+
parse_rdf_serialization(response, **options)
|
378
406
|
end
|
379
407
|
end
|
380
408
|
|
381
409
|
##
|
382
410
|
# @param [String, Hash] json
|
383
411
|
# @return [<RDF::Query::Solutions>]
|
384
|
-
# @see
|
412
|
+
# @see https://www.w3.org/TR/rdf-sparql-json-res/#results
|
385
413
|
def self.parse_json_bindings(json, nodes = {})
|
386
414
|
require 'json' unless defined?(::JSON)
|
387
415
|
json = JSON.parse(json.to_s) unless json.is_a?(Hash)
|
@@ -402,8 +430,8 @@ module SPARQL
|
|
402
430
|
##
|
403
431
|
# @param [Hash{String => String}] value
|
404
432
|
# @return [RDF::Value]
|
405
|
-
# @see
|
406
|
-
# @see
|
433
|
+
# @see https://www.w3.org/TR/sparql11-results-json/#select-encode-terms
|
434
|
+
# @see https://www.w3.org/TR/rdf-sparql-json-res/#variable-binding-results
|
407
435
|
def self.parse_json_value(value, nodes = {})
|
408
436
|
case value['type'].to_sym
|
409
437
|
when :bnode
|
@@ -411,9 +439,14 @@ module SPARQL
|
|
411
439
|
when :uri
|
412
440
|
RDF::URI.new(value['value'])
|
413
441
|
when :literal
|
414
|
-
RDF::Literal.new(value['value'], :
|
442
|
+
RDF::Literal.new(value['value'], datatype: value['datatype'], language: value['xml:lang'])
|
415
443
|
when :'typed-literal'
|
416
|
-
RDF::Literal.new(value['value'], :
|
444
|
+
RDF::Literal.new(value['value'], datatype: value['datatype'])
|
445
|
+
when :triple
|
446
|
+
s = parse_json_value(value['value']['subject'], nodes)
|
447
|
+
p = parse_json_value(value['value']['predicate'], nodes)
|
448
|
+
o = parse_json_value(value['value']['object'], nodes)
|
449
|
+
RDF::Statement(s, p, o)
|
417
450
|
else nil
|
418
451
|
end
|
419
452
|
end
|
@@ -421,7 +454,7 @@ module SPARQL
|
|
421
454
|
##
|
422
455
|
# @param [String, Array<Array<String>>] csv
|
423
456
|
# @return [<RDF::Query::Solutions>]
|
424
|
-
# @see
|
457
|
+
# @see https://www.w3.org/TR/sparql11-results-csv-tsv/
|
425
458
|
def self.parse_csv_bindings(csv, nodes = {})
|
426
459
|
require 'csv' unless defined?(::CSV)
|
427
460
|
csv = CSV.parse(csv.to_s) unless csv.is_a?(Array)
|
@@ -445,7 +478,7 @@ module SPARQL
|
|
445
478
|
##
|
446
479
|
# @param [String, Array<Array<String>>] tsv
|
447
480
|
# @return [<RDF::Query::Solutions>]
|
448
|
-
# @see
|
481
|
+
# @see https://www.w3.org/TR/sparql11-results-csv-tsv/
|
449
482
|
def self.parse_tsv_bindings(tsv, nodes = {})
|
450
483
|
tsv = tsv.lines.map {|l| l.chomp.split("\t")} unless tsv.is_a?(Array)
|
451
484
|
vars = tsv.shift.map {|h| h.sub(/^\?/, '')}
|
@@ -474,7 +507,7 @@ module SPARQL
|
|
474
507
|
##
|
475
508
|
# @param [String, IO, Nokogiri::XML::Node, REXML::Element] xml
|
476
509
|
# @return [<RDF::Query::Solutions>]
|
477
|
-
# @see
|
510
|
+
# @see https://www.w3.org/TR/rdf-sparql-json-res/#results
|
478
511
|
def self.parse_xml_bindings(xml, nodes = {})
|
479
512
|
xml.force_encoding(::Encoding::UTF_8) if xml.respond_to?(:force_encoding)
|
480
513
|
|
@@ -519,7 +552,7 @@ module SPARQL
|
|
519
552
|
##
|
520
553
|
# @param [Nokogiri::XML::Element, REXML::Element] value
|
521
554
|
# @return [RDF::Value]
|
522
|
-
# @see
|
555
|
+
# @see https://www.w3.org/TR/rdf-sparql-json-res/#variable-binding-results
|
523
556
|
def self.parse_xml_value(value, nodes = {})
|
524
557
|
case value.name.to_sym
|
525
558
|
when :bnode
|
@@ -529,7 +562,12 @@ module SPARQL
|
|
529
562
|
when :literal
|
530
563
|
lang = value.respond_to?(:attr) ? value.attr('xml:lang') : value.attributes['xml:lang']
|
531
564
|
datatype = value.respond_to?(:attr) ? value.attr('datatype') : value.attributes['datatype']
|
532
|
-
RDF::Literal.new(value.text, :
|
565
|
+
RDF::Literal.new(value.text, language: lang, datatype: datatype)
|
566
|
+
when :triple
|
567
|
+
# Note, this is order dependent
|
568
|
+
res = value.elements.map {|e| e.elements.to_a}.
|
569
|
+
flatten.map {|e| parse_xml_value(e, nodes)}
|
570
|
+
RDF::Statement(*res)
|
533
571
|
else nil
|
534
572
|
end
|
535
573
|
end
|
@@ -538,8 +576,8 @@ module SPARQL
|
|
538
576
|
# @param [Net::HTTPSuccess] response
|
539
577
|
# @param [Hash{Symbol => Object}] options
|
540
578
|
# @return [RDF::Enumerable]
|
541
|
-
def parse_rdf_serialization(response, options
|
542
|
-
options = {:
|
579
|
+
def parse_rdf_serialization(response, **options)
|
580
|
+
options = {content_type: response.content_type} unless options[:content_type]
|
543
581
|
if reader = RDF::Reader.for(options)
|
544
582
|
reader.new(response.body)
|
545
583
|
else
|
@@ -615,7 +653,7 @@ module SPARQL
|
|
615
653
|
RDF::Statement.from(pattern).to_triple.each_with_index.map do |v, i|
|
616
654
|
if i == 1
|
617
655
|
SPARQL::Client.serialize_predicate(v)
|
618
|
-
|
656
|
+
else
|
619
657
|
SPARQL::Client.serialize_value(v, use_vars)
|
620
658
|
end
|
621
659
|
end
|
@@ -658,11 +696,7 @@ module SPARQL
|
|
658
696
|
value = ENV['https_proxy']
|
659
697
|
proxy_url = URI.parse(value) unless value.nil? || value.empty?
|
660
698
|
end
|
661
|
-
klass =
|
662
|
-
Net::HTTP::Persistent.new(name: self.class.to_s, proxy: proxy_url)
|
663
|
-
else
|
664
|
-
Net::HTTP::Persistent.new(self.class.to_s, proxy_url)
|
665
|
-
end
|
699
|
+
klass = Net::HTTP::Persistent.new(name: self.class.to_s, proxy: proxy_url)
|
666
700
|
klass.keep_alive = @options[:keep_alive] || 120
|
667
701
|
klass.read_timeout = @options[:read_timeout] || 60
|
668
702
|
klass
|
@@ -673,10 +707,16 @@ module SPARQL
|
|
673
707
|
#
|
674
708
|
# @param [String, #to_s] query
|
675
709
|
# @param [Hash{String => String}] headers
|
710
|
+
# HTTP Request headers
|
711
|
+
#
|
712
|
+
# Defaults `Accept` header based on available reader content types if triples are expected and to SPARQL result types otherwise, to allow for content negotiation based on available readers.
|
713
|
+
#
|
714
|
+
# Defaults `User-Agent` header, unless one is specified.
|
676
715
|
# @yield [response]
|
677
716
|
# @yieldparam [Net::HTTPResponse] response
|
678
717
|
# @return [Net::HTTPResponse]
|
679
|
-
# @
|
718
|
+
# @raise [IOError] if connection is closed
|
719
|
+
# @see https://www.w3.org/TR/sparql11-protocol/#query-operation
|
680
720
|
def request(query, headers = {}, &block)
|
681
721
|
# Make sure an appropriate Accept header is present
|
682
722
|
headers['Accept'] ||= if (query.respond_to?(:expects_statements?) ?
|
@@ -686,6 +726,7 @@ module SPARQL
|
|
686
726
|
else
|
687
727
|
RESULT_ALL
|
688
728
|
end
|
729
|
+
headers['User-Agent'] ||= "Ruby SPARQL::Client/#{SPARQL::Client::VERSION}"
|
689
730
|
|
690
731
|
request = send("make_#{request_method(query)}_request", query, headers)
|
691
732
|
|
@@ -693,6 +734,7 @@ module SPARQL
|
|
693
734
|
|
694
735
|
pre_http_hook(request) if respond_to?(:pre_http_hook)
|
695
736
|
|
737
|
+
raise IOError, "Client has been closed" unless @http
|
696
738
|
response = @http.request(::URI.parse(url.to_s), request)
|
697
739
|
|
698
740
|
post_http_hook(response) if respond_to?(:post_http_hook)
|
@@ -722,10 +764,10 @@ module SPARQL
|
|
722
764
|
# @param [String, #to_s] query
|
723
765
|
# @param [Hash{String => String}] headers
|
724
766
|
# @return [Net::HTTPRequest]
|
725
|
-
# @see
|
767
|
+
# @see https://www.w3.org/TR/sparql11-protocol/#query-via-get
|
726
768
|
def make_get_request(query, headers = {})
|
727
769
|
url = self.url.dup
|
728
|
-
url.query_values = (url.query_values || {}).merge(:
|
770
|
+
url.query_values = (url.query_values || {}).merge(query: query.to_s)
|
729
771
|
set_url_default_graph url unless @options[:graph].nil?
|
730
772
|
request = Net::HTTP::Get.new(url.request_uri, self.headers.merge(headers))
|
731
773
|
request
|
@@ -737,8 +779,8 @@ module SPARQL
|
|
737
779
|
# @param [String, #to_s] query
|
738
780
|
# @param [Hash{String => String}] headers
|
739
781
|
# @return [Net::HTTPRequest]
|
740
|
-
# @see
|
741
|
-
# @see
|
782
|
+
# @see https://www.w3.org/TR/sparql11-protocol/#query-via-post-direct
|
783
|
+
# @see https://www.w3.org/TR/sparql11-protocol/#query-via-post-urlencoded
|
742
784
|
def make_post_request(query, headers = {})
|
743
785
|
if @alt_endpoint.nil?
|
744
786
|
url = self.url.dup
|