sparql-client 3.2.0 → 3.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +9 -9
- data/VERSION +1 -1
- data/lib/sparql/client/query.rb +124 -46
- data/lib/sparql/client.rb +68 -40
- metadata +20 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c9eca6a3f6e57b16150e55c6a595c616c4b8b58778772e619168e5dd19c05a5
|
4
|
+
data.tar.gz: 5c383ab056d6f28951a366a5cb546f3aa900e7c81170b2f42a04ce72167deea8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 12f686f4d066f3539de0fd3924895bbd854d2998f4b666d60e58df2efac33343c214588ff19b5ed759d8f2c481f8c3ff5a02f9f432fe55977a56e4080029d8c1
|
7
|
+
data.tar.gz: 4168b202c647758fffb13ad0a6445b46d797a34482764cdc5efb3a9e36a258c0157e03f958eaf5a96530453210afbbcc986aa0b3374a849dde73a9f090d15b6d
|
data/README.md
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
This is a [Ruby][] implementation of a [SPARQL][] client for [RDF.rb][].
|
4
4
|
|
5
|
-
* <https://ruby-rdf.github.
|
5
|
+
* <https://ruby-rdf.github.io/sparql-client/>
|
6
6
|
|
7
|
-
[![Gem Version](https://badge.fury.io/rb/sparql-client.
|
7
|
+
[![Gem Version](https://badge.fury.io/rb/sparql-client.svg)](https://badge.fury.io/rb/sparql-client)
|
8
8
|
[![Build Status](https://github.com/ruby-rdf/sparql-client/workflows/CI/badge.svg?branch=develop)](https://github.com/ruby-rdf/sparql-client/actions?query=workflow%3ACI)
|
9
9
|
[![Coverage Status](https://coveralls.io/repos/ruby-rdf/sparql-client/badge.svg?branch=master&service=github)](https://coveralls.io/github/ruby-rdf/sparql-client?branch=master)
|
10
10
|
[![Gitter chat](https://badges.gitter.im/ruby-rdf/rdf.png)](https://gitter.im/ruby-rdf/rdf)
|
@@ -44,7 +44,7 @@ sparql = SPARQL::Client.new("http://dbpedia.org/sparql", headers: {'User-Agent'
|
|
44
44
|
|
45
45
|
```ruby
|
46
46
|
require 'sparql/client'
|
47
|
-
sparql = SPARQL::Client.new("http://dbpedia.org/sparql",
|
47
|
+
sparql = SPARQL::Client.new("http://dbpedia.org/sparql", graph: "http://dbpedia.org")
|
48
48
|
```
|
49
49
|
|
50
50
|
|
@@ -117,10 +117,10 @@ sparql.delete_data(data)
|
|
117
117
|
|
118
118
|
## Documentation
|
119
119
|
|
120
|
-
* [SPARQL::Client](https://
|
121
|
-
* [SPARQL::Client::Query](https://
|
122
|
-
* [SPARQL::Client::Repository](https://
|
123
|
-
* [SPARQL::Client::Update](https://
|
120
|
+
* [SPARQL::Client](https://ruby-rdf.github.io/sparql-client/SPARQL/Client)
|
121
|
+
* [SPARQL::Client::Query](https://ruby-rdf.github.io/sparql-client/SPARQL/Client/Query)
|
122
|
+
* [SPARQL::Client::Repository](https://ruby-rdf.github.io/sparql-client/SPARQL/Client/Repository)
|
123
|
+
* [SPARQL::Client::Update](https://ruby-rdf.github.io/sparql-client/SPARQL/Client/Update)
|
124
124
|
|
125
125
|
## Dependencies
|
126
126
|
|
@@ -191,7 +191,7 @@ This repository uses [Git Flow](https://github.com/nvie/gitflow) to mange develo
|
|
191
191
|
|
192
192
|
## Resources
|
193
193
|
|
194
|
-
* <https://ruby-rdf.github.
|
194
|
+
* <https://ruby-rdf.github.io/sparql-client/>
|
195
195
|
* <https://github.com/ruby-rdf/sparql-client>
|
196
196
|
* <https://rubygems.org/gems/sparql-client>
|
197
197
|
* <https://raa.ruby-lang.org/project/sparql-client/>
|
@@ -207,7 +207,7 @@ see <https://unlicense.org/> or the accompanying {file:UNLICENSE} file.
|
|
207
207
|
[SPARQL]: https://en.wikipedia.org/wiki/SPARQL
|
208
208
|
[SPARQL JSON]: https://www.w3.org/TR/rdf-sparql-json-res/
|
209
209
|
[RDF.rb]: https://rubygems.org/gems/rdf
|
210
|
-
[RDF::Repository]: https://
|
210
|
+
[RDF::Repository]: https://ruby-rdf.github.io/rdf/RDF/Repository
|
211
211
|
[DSL]: https://en.wikipedia.org/wiki/Domain-specific_language
|
212
212
|
"domain-specific language"
|
213
213
|
[YARD]: https://yardoc.org/
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
3.2.
|
1
|
+
3.2.2
|
data/lib/sparql/client/query.rb
CHANGED
@@ -111,7 +111,7 @@ class SPARQL::Client
|
|
111
111
|
|
112
112
|
##
|
113
113
|
# @example ASK WHERE { ?s ?p ?o . }
|
114
|
-
#
|
114
|
+
# Query.ask.where([:s, :p, :o])
|
115
115
|
#
|
116
116
|
# @return [Query]
|
117
117
|
# @see https://www.w3.org/TR/sparql11-query/#ask
|
@@ -122,13 +122,13 @@ class SPARQL::Client
|
|
122
122
|
|
123
123
|
##
|
124
124
|
# @example `SELECT * WHERE { ?s ?p ?o . }`
|
125
|
-
#
|
125
|
+
# Query.select.where([:s, :p, :o])
|
126
126
|
#
|
127
127
|
# @example `SELECT ?s WHERE {?s ?p ?o .}`
|
128
|
-
#
|
128
|
+
# Query.select(:s).where([:s, :p, :o])
|
129
129
|
#
|
130
130
|
# @example `SELECT COUNT(?uri as ?c) WHERE {?uri a owl:Class}`
|
131
|
-
#
|
131
|
+
# Query.select(count: {uri: :c}).where([:uri, RDF.type, RDF::OWL.Class])
|
132
132
|
#
|
133
133
|
# @param [Array<Symbol>, Hash{Symbol => RDF::Query::Variable}] variables
|
134
134
|
# @return [Query]
|
@@ -144,7 +144,7 @@ class SPARQL::Client
|
|
144
144
|
|
145
145
|
##
|
146
146
|
# @example DESCRIBE * WHERE { ?s ?p ?o . }
|
147
|
-
#
|
147
|
+
# Query.describe.where([:s, :p, :o])
|
148
148
|
#
|
149
149
|
# @param [Array<Symbol>] variables
|
150
150
|
# @return [Query]
|
@@ -158,7 +158,7 @@ class SPARQL::Client
|
|
158
158
|
|
159
159
|
##
|
160
160
|
# @example CONSTRUCT { ?s ?p ?o . } WHERE { ?s ?p ?o . }
|
161
|
-
#
|
161
|
+
# Query.construct([:s, :p, :o]).where([:s, :p, :o])
|
162
162
|
#
|
163
163
|
# @param [Array<RDF::Query::Pattern, Array>] patterns
|
164
164
|
# @return [Query]
|
@@ -170,7 +170,7 @@ class SPARQL::Client
|
|
170
170
|
|
171
171
|
##
|
172
172
|
# @example SELECT * FROM <a> WHERE \{ ?s ?p ?o . \}
|
173
|
-
#
|
173
|
+
# Query.select.from(RDF::URI.new(a)).where([:s, :p, :o])
|
174
174
|
#
|
175
175
|
# @param [RDF::URI] uri
|
176
176
|
# @return [Query]
|
@@ -182,22 +182,22 @@ class SPARQL::Client
|
|
182
182
|
|
183
183
|
##
|
184
184
|
# @example SELECT * WHERE { ?s ?p ?o . }
|
185
|
-
#
|
186
|
-
#
|
185
|
+
# Query.select.where([:s, :p, :o])
|
186
|
+
# Query.select.whether([:s, :p, :o])
|
187
187
|
#
|
188
188
|
# @example SELECT * WHERE { { SELECT * WHERE { ?s ?p ?o . } } . ?s ?p ?o . }
|
189
|
-
# subquery =
|
190
|
-
#
|
189
|
+
# subquery = Query.select.where([:s, :p, :o])
|
190
|
+
# Query.select.where([:s, :p, :o], subquery)
|
191
191
|
#
|
192
192
|
# @example SELECT * WHERE { { SELECT * WHERE { ?s ?p ?o . } } . ?s ?p ?o . }
|
193
|
-
#
|
193
|
+
# Query.select.where([:s, :p, :o]) do |q|
|
194
194
|
# q.select.where([:s, :p, :o])
|
195
195
|
# end
|
196
196
|
#
|
197
197
|
# Block form can be used for chaining calls in addition to creating sub-select queries.
|
198
198
|
#
|
199
199
|
# @example SELECT * WHERE { ?s ?p ?o . } ORDER BY ?o
|
200
|
-
#
|
200
|
+
# Query.select.where([:s, :p, :o]) do
|
201
201
|
# order(:o)
|
202
202
|
# end
|
203
203
|
#
|
@@ -236,14 +236,14 @@ class SPARQL::Client
|
|
236
236
|
|
237
237
|
##
|
238
238
|
# @example SELECT * WHERE { ?s ?p ?o . } ORDER BY ?o
|
239
|
-
#
|
240
|
-
#
|
239
|
+
# Query.select.where([:s, :p, :o]).order(:o)
|
240
|
+
# Query.select.where([:s, :p, :o]).order_by(:o)
|
241
241
|
#
|
242
242
|
# @example SELECT * WHERE { ?s ?p ?o . } ORDER BY ?o ?p
|
243
|
-
#
|
243
|
+
# Query.select.where([:s, :p, :o]).order_by(:o, :p)
|
244
244
|
#
|
245
245
|
# @example SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o) DESC(?p)
|
246
|
-
#
|
246
|
+
# Query.select.where([:s, :p, :o]).order_by(o: :asc, p: :desc)
|
247
247
|
#
|
248
248
|
# @param [Array<Symbol, String>] variables
|
249
249
|
# @return [Query]
|
@@ -257,8 +257,8 @@ class SPARQL::Client
|
|
257
257
|
|
258
258
|
##
|
259
259
|
# @example SELECT * WHERE { ?s ?p ?o . } ORDER BY ASC(?o)
|
260
|
-
#
|
261
|
-
#
|
260
|
+
# Query.select.where([:s, :p, :o]).order.asc(:o)
|
261
|
+
# Query.select.where([:s, :p, :o]).asc(:o)
|
262
262
|
#
|
263
263
|
# @param [Array<Symbol, String>] var
|
264
264
|
# @return [Query]
|
@@ -270,8 +270,8 @@ class SPARQL::Client
|
|
270
270
|
|
271
271
|
##
|
272
272
|
# @example SELECT * WHERE { ?s ?p ?o . } ORDER BY DESC(?o)
|
273
|
-
#
|
274
|
-
#
|
273
|
+
# Query.select.where([:s, :p, :o]).order.desc(:o)
|
274
|
+
# Query.select.where([:s, :p, :o]).desc(:o)
|
275
275
|
#
|
276
276
|
# @param [Array<Symbol, String>] var
|
277
277
|
# @return [Query]
|
@@ -283,7 +283,7 @@ class SPARQL::Client
|
|
283
283
|
|
284
284
|
##
|
285
285
|
# @example SELECT ?s WHERE { ?s ?p ?o . } GROUP BY ?s
|
286
|
-
#
|
286
|
+
# Query.select(:s).where([:s, :p, :o]).group_by(:s)
|
287
287
|
#
|
288
288
|
# @param [Array<Symbol, String>] variables
|
289
289
|
# @return [Query]
|
@@ -297,7 +297,7 @@ class SPARQL::Client
|
|
297
297
|
|
298
298
|
##
|
299
299
|
# @example SELECT DISTINCT ?s WHERE { ?s ?p ?o . }
|
300
|
-
#
|
300
|
+
# Query.select(:s).distinct.where([:s, :p, :o])
|
301
301
|
#
|
302
302
|
# @return [Query]
|
303
303
|
# @see https://www.w3.org/TR/sparql11-query/#modDuplicates
|
@@ -308,7 +308,7 @@ class SPARQL::Client
|
|
308
308
|
|
309
309
|
##
|
310
310
|
# @example SELECT REDUCED ?s WHERE { ?s ?p ?o . }
|
311
|
-
#
|
311
|
+
# Query.select(:s).reduced.where([:s, :p, :o])
|
312
312
|
#
|
313
313
|
# @return [Query]
|
314
314
|
# @see https://www.w3.org/TR/sparql11-query/#modDuplicates
|
@@ -319,7 +319,8 @@ class SPARQL::Client
|
|
319
319
|
|
320
320
|
##
|
321
321
|
# @example SELECT * WHERE { GRAPH ?g { ?s ?p ?o . } }
|
322
|
-
#
|
322
|
+
# Query.select.graph(:g).where([:s, :p, :o])
|
323
|
+
#
|
323
324
|
# @param [RDF::Value] graph_uri_or_var
|
324
325
|
# @return [Query]
|
325
326
|
# @see https://www.w3.org/TR/sparql11-query/#queryDataset
|
@@ -335,7 +336,7 @@ class SPARQL::Client
|
|
335
336
|
|
336
337
|
##
|
337
338
|
# @example SELECT * WHERE { ?s ?p ?o . } OFFSET 100
|
338
|
-
#
|
339
|
+
# Query.select.where([:s, :p, :o]).offset(100)
|
339
340
|
#
|
340
341
|
# @param [Integer, #to_i] start
|
341
342
|
# @return [Query]
|
@@ -346,7 +347,7 @@ class SPARQL::Client
|
|
346
347
|
|
347
348
|
##
|
348
349
|
# @example SELECT * WHERE { ?s ?p ?o . } LIMIT 10
|
349
|
-
#
|
350
|
+
# Query.select.where([:s, :p, :o]).limit(10)
|
350
351
|
#
|
351
352
|
# @param [Integer, #to_i] length
|
352
353
|
# @return [Query]
|
@@ -357,7 +358,7 @@ class SPARQL::Client
|
|
357
358
|
|
358
359
|
##
|
359
360
|
# @example SELECT * WHERE { ?s ?p ?o . } OFFSET 100 LIMIT 10
|
360
|
-
#
|
361
|
+
# Query.select.where([:s, :p, :o]).slice(100, 10)
|
361
362
|
#
|
362
363
|
# @param [Integer, #to_i] start
|
363
364
|
# @param [Integer, #to_i] length
|
@@ -371,7 +372,7 @@ class SPARQL::Client
|
|
371
372
|
##
|
372
373
|
# @overload prefix(prefix: uri)
|
373
374
|
# @example PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT * WHERE \{ ?s ?p ?o . \}
|
374
|
-
#
|
375
|
+
# Query.select.
|
375
376
|
# prefix(dc: RDF::URI("http://purl.org/dc/elements/1.1/")).
|
376
377
|
# prefix(foaf: RDF::URI("http://xmlns.com/foaf/0.1/")).
|
377
378
|
# where([:s, :p, :o])
|
@@ -382,7 +383,7 @@ class SPARQL::Client
|
|
382
383
|
#
|
383
384
|
# @overload prefix(string)
|
384
385
|
# @example PREFIX dc: <http://purl.org/dc/elements/1.1/> PREFIX foaf: <http://xmlns.com/foaf/0.1/> SELECT * WHERE \{ ?s ?p ?o . \}
|
385
|
-
#
|
386
|
+
# Query.select.
|
386
387
|
# prefix("dc: <http://purl.org/dc/elements/1.1/>").
|
387
388
|
# prefix("foaf: <http://xmlns.com/foaf/0.1/>").
|
388
389
|
# where([:s, :p, :o])
|
@@ -406,13 +407,13 @@ class SPARQL::Client
|
|
406
407
|
|
407
408
|
##
|
408
409
|
# @example SELECT * WHERE \{ ?s ?p ?o . OPTIONAL \{ ?s a ?o . ?s \<http://purl.org/dc/terms/abstract\> ?o . \} \}
|
409
|
-
#
|
410
|
+
# Query.select.where([:s, :p, :o]).
|
410
411
|
# optional([:s, RDF.type, :o], [:s, RDF::Vocab::DC.abstract, :o])
|
411
412
|
#
|
412
413
|
# The block form can be used for adding filters:
|
413
414
|
#
|
414
415
|
# @example ASK WHERE { ?s ?p ?o . OPTIONAL { ?s ?p ?o . FILTER(regex(?s, 'Abiline, Texas'))} }
|
415
|
-
#
|
416
|
+
# Query.ask.where([:s, :p, :o]).optional([:s, :p, :o]) do
|
416
417
|
# filter("regex(?s, 'Abiline, Texas')")
|
417
418
|
# end
|
418
419
|
#
|
@@ -441,22 +442,89 @@ class SPARQL::Client
|
|
441
442
|
self
|
442
443
|
end
|
443
444
|
|
445
|
+
##
|
446
|
+
# Federated Queries via the SERVICE keyword.
|
447
|
+
#
|
448
|
+
# Supports limited use of the SERVICE keyword with an endpoint term, a sequence of patterns, a query, or a block.
|
449
|
+
#
|
450
|
+
# @example SELECT * WHERE \{ ?s ?p1 ?o1 . SERVICE ?l \{ ?s ?p2 ?o2 \} \}
|
451
|
+
# Query.select.where([:s, :p1, :o1]).
|
452
|
+
# service(:l, [:s, :p2, :o2])
|
453
|
+
#
|
454
|
+
# @example SELECT * WHERE \{ ?book <http://purl.org/dc/terms/title> ?title . SERVICE ?l \{ ?book <http://purl.org/dc/elements/1.1/title> ?title . FILTER(langmatches(?title, 'en')) \} \}
|
455
|
+
# query1 = SPARQL::Client::Query.select.
|
456
|
+
# where([:book, RDF::Vocab::DC11.title, :title]).
|
457
|
+
# filter("langmatches(?title, 'en')")
|
458
|
+
# Query.select.where([:book, RDF::Vocab::DC.title, :title]).service(?l, query1)
|
459
|
+
#
|
460
|
+
# The block form can be used for more complicated queries, using the `select` form (note, use either block or argument forms, not both):
|
461
|
+
#
|
462
|
+
# @example SELECT * WHERE \{ ?book dc:title ?title \} SERVICE ?l \{ ?book dc11:title ?title \}
|
463
|
+
# query1 = SPARQL::Client::Query.select.where([:book, RDF::Vocab::DC11.title, :title])
|
464
|
+
# Query.select.where([:book, RDF::Vocab::DC.title, :title]).service :l do |q|
|
465
|
+
# q.select.
|
466
|
+
# where([:book, RDF::Vocab::DC11.title, :title])
|
467
|
+
# end
|
468
|
+
#
|
469
|
+
# @example SELECT * WHERE \{ ?s ?p1 ?o1 . SERVICE SILENT ?l \{ ?s ?p2 ?o2 \} \}
|
470
|
+
# Query.select.where([:s, :p1, :o1]).
|
471
|
+
# service(:l, [:s, :p2, :o2], silent: true)
|
472
|
+
#
|
473
|
+
# @param [Array<RDF::Query::Pattern, Array>] patterns
|
474
|
+
# splat of zero or more patterns followed by zero or more queries.
|
475
|
+
# @param [Boolean] silent
|
476
|
+
# @yield [query]
|
477
|
+
# Yield form with or without argument; without an argument, evaluates within the query.
|
478
|
+
# @yieldparam [SPARQL::Client::Query] query used for adding select clauses.
|
479
|
+
# @return [Query]
|
480
|
+
# @see https://www.w3.org/TR/sparql11-federated-query/
|
481
|
+
def service(endpoint, *patterns, silent: false, &block)
|
482
|
+
service = {
|
483
|
+
endpoint: (endpoint.is_a?(Symbol) ? RDF::Query::Variable.new(endpoint) : endpoint),
|
484
|
+
silent: silent,
|
485
|
+
query: nil
|
486
|
+
}
|
487
|
+
(options[:services] ||= []) << service
|
488
|
+
|
489
|
+
if block_given?
|
490
|
+
raise ArgumentError, "#service requires either arguments or a block, not both." unless patterns.empty?
|
491
|
+
# Evaluate calls in a new query instance
|
492
|
+
query = self.class.select.where
|
493
|
+
case block.arity
|
494
|
+
when 1 then block.call(query)
|
495
|
+
else query.instance_eval(&block)
|
496
|
+
end
|
497
|
+
service[:query] = query
|
498
|
+
elsif patterns.all? {|p| p.is_a?(SPARQL::Client::Query)}
|
499
|
+
# With argument form, all must be patterns or queries
|
500
|
+
raise ArgumentError, "#service arguments are triple patterns or a query, not both." if patterns.length != 1
|
501
|
+
service[:query] = patterns.first
|
502
|
+
elsif patterns.all? {|p| p.is_a?(Array)}
|
503
|
+
# With argument form, all must be patterns, or queries
|
504
|
+
service[:query] = self.class.select.where(*patterns)
|
505
|
+
else
|
506
|
+
raise ArgumentError, "#service arguments are triple patterns a query, not both."
|
507
|
+
end
|
508
|
+
|
509
|
+
self
|
510
|
+
end
|
511
|
+
|
444
512
|
##
|
445
513
|
# @example SELECT * WHERE \{ ?book dc:title ?title \} UNION \{ ?book dc11:title ?title \}
|
446
|
-
#
|
514
|
+
# Query.select.where([:book, RDF::Vocab::DC.title, :title]).
|
447
515
|
# union([:book, RDF::Vocab::DC11.title, :title])
|
448
516
|
#
|
449
517
|
# @example SELECT * WHERE \{ ?book dc:title ?title \} UNION \{ ?book dc11:title ?title . FILTER(langmatches(lang(?title), 'EN'))\}
|
450
518
|
# query1 = SPARQL::Client::Query.select.
|
451
519
|
# where([:book, RDF::Vocab::DC11.title, :title]).
|
452
520
|
# filter("langmatches(?title, 'en')")
|
453
|
-
#
|
521
|
+
# Query.select.where([:book, RDF::Vocab::DC.title, :title]).union(query1)
|
454
522
|
#
|
455
523
|
# The block form can be used for more complicated queries, using the `select` form (note, use either block or argument forms, not both):
|
456
524
|
#
|
457
525
|
# @example SELECT * WHERE \{ ?book dc:title ?title \} UNION \{ ?book dc11:title ?title . FILTER(langmatches(lang(?title), 'EN'))\}
|
458
526
|
# query1 = SPARQL::Client::Query.select.where([:book, RDF::Vocab::DC11.title, :title]).filter("langmatches(?title, 'en')")
|
459
|
-
#
|
527
|
+
# Query.select.where([:book, RDF::Vocab::DC.title, :title]).union do |q|
|
460
528
|
# q.select.
|
461
529
|
# where([:book, RDF::Vocab::DC11.title, :title]).
|
462
530
|
# filter("langmatches(?title, 'en')")
|
@@ -468,7 +536,7 @@ class SPARQL::Client
|
|
468
536
|
# Yield form with or without argument; without an argument, evaluates within the query.
|
469
537
|
# @yieldparam [SPARQL::Client::Query] query used for adding select clauses.
|
470
538
|
# @return [Query]
|
471
|
-
# @see https://www.w3.org/TR/sparql11-query/#
|
539
|
+
# @see https://www.w3.org/TR/sparql11-query/#alternatives
|
472
540
|
def union(*patterns, &block)
|
473
541
|
options[:unions] ||= []
|
474
542
|
|
@@ -488,7 +556,7 @@ class SPARQL::Client
|
|
488
556
|
# With argument form, all must be patterns, or queries
|
489
557
|
options[:unions] << self.class.select.where(*patterns)
|
490
558
|
else
|
491
|
-
raise ArgumentError, "#union arguments are triple
|
559
|
+
raise ArgumentError, "#union arguments are triple patterns or queries, not both."
|
492
560
|
end
|
493
561
|
|
494
562
|
self
|
@@ -496,20 +564,20 @@ class SPARQL::Client
|
|
496
564
|
|
497
565
|
##
|
498
566
|
# @example SELECT * WHERE \{ ?book dc:title ?title . MINUS \{ ?book dc11:title ?title \} \}
|
499
|
-
#
|
567
|
+
# Query.select.where([:book, RDF::Vocab::DC.title, :title]).
|
500
568
|
# minus([:book, RDF::Vocab::DC11.title, :title])
|
501
569
|
#
|
502
570
|
# @example SELECT * WHERE \{ ?book dc:title ?title MINUS \{ ?book dc11:title ?title . FILTER(langmatches(lang(?title), 'EN')) \} \}
|
503
571
|
# query1 = SPARQL::Client::Query.select.
|
504
572
|
# where([:book, RDF::Vocab::DC11.title, :title]).
|
505
573
|
# filter("langmatches(?title, 'en')")
|
506
|
-
#
|
574
|
+
# Query.select.where([:book, RDF::Vocab::DC.title, :title]).minus(query1)
|
507
575
|
#
|
508
576
|
# The block form can be used for more complicated queries, using the `select` form (note, use either block or argument forms, not both):
|
509
577
|
#
|
510
578
|
# @example SELECT * WHERE \{ ?book dc:title ?title MINUS \{ ?book dc11:title ?title . FILTER(langmatches(lang(?title), 'EN'))\} \}
|
511
579
|
# query1 = SPARQL::Client::Query.select.where([:book, RDF::Vocab::DC11.title, :title]).filter("langmatches(?title, 'en')")
|
512
|
-
#
|
580
|
+
# Query.select.where([:book, RDF::Vocab::DC.title, :title]).minus do |q|
|
513
581
|
# q.select.
|
514
582
|
# where([:book, RDF::Vocab::DC11.title, :title]).
|
515
583
|
# filter("langmatches(?title, 'en')")
|
@@ -521,7 +589,7 @@ class SPARQL::Client
|
|
521
589
|
# Yield form with or without argument; without an argument, evaluates within the query.
|
522
590
|
# @yieldparam [SPARQL::Client::Query] query used for adding select clauses.
|
523
591
|
# @return [Query]
|
524
|
-
# @see https://www.w3.org/TR/sparql11-query/#
|
592
|
+
# @see https://www.w3.org/TR/sparql11-query/#negation
|
525
593
|
def minus(*patterns, &block)
|
526
594
|
options[:minuses] ||= []
|
527
595
|
|
@@ -541,7 +609,7 @@ class SPARQL::Client
|
|
541
609
|
# With argument form, all must be patterns, or queries
|
542
610
|
options[:minuses] << self.class.select.where(*patterns)
|
543
611
|
else
|
544
|
-
raise ArgumentError, "#minus arguments are triple
|
612
|
+
raise ArgumentError, "#minus arguments are triple patterns or queries, not both."
|
545
613
|
end
|
546
614
|
|
547
615
|
self
|
@@ -557,12 +625,12 @@ class SPARQL::Client
|
|
557
625
|
#
|
558
626
|
# @overload values(vars, *data)
|
559
627
|
# @example single variable with multiple values
|
560
|
-
#
|
628
|
+
# Query.select
|
561
629
|
# .where([:s, RDF::URI('http://purl.org/dc/terms/title'), :title])
|
562
630
|
# .values(:title, "This title", "Another title")
|
563
631
|
#
|
564
632
|
# @example multiple variables with multiple values
|
565
|
-
#
|
633
|
+
# Query.select
|
566
634
|
# .where([:s, RDF::URI('http://purl.org/dc/terms/title'), :title],
|
567
635
|
# [:s, RDF.type, :type])
|
568
636
|
# .values([:type, :title],
|
@@ -570,7 +638,7 @@ class SPARQL::Client
|
|
570
638
|
# [RDF::URI('http://pcdm.org/models#Collection', 'Another title'])
|
571
639
|
#
|
572
640
|
# @example multiple variables with UNDEF
|
573
|
-
#
|
641
|
+
# Query.select
|
574
642
|
# .where([:s, RDF::URI('http://purl.org/dc/terms/title'), :title],
|
575
643
|
# [:s, RDF.type, :type])
|
576
644
|
# .values([:type, :title],
|
@@ -626,7 +694,7 @@ class SPARQL::Client
|
|
626
694
|
|
627
695
|
##
|
628
696
|
# @example ASK WHERE { ?s ?p ?o . FILTER(regex(?s, 'Abiline, Texas')) }
|
629
|
-
#
|
697
|
+
# Query.ask.where([:s, :p, :o]).filter("regex(?s, 'Abiline, Texas')")
|
630
698
|
# @return [Query]
|
631
699
|
def filter(string)
|
632
700
|
((options[:filters] ||= []) << Filter.new(string)) if string and not string.empty?
|
@@ -796,6 +864,16 @@ class SPARQL::Client
|
|
796
864
|
if options[:filters]
|
797
865
|
buffer += options[:filters].map(&:to_s)
|
798
866
|
end
|
867
|
+
|
868
|
+
if options[:services]
|
869
|
+
options[:services].each do |service|
|
870
|
+
buffer << 'SERVICE'
|
871
|
+
buffer << 'SILENT' if service[:silent]
|
872
|
+
buffer << SPARQL::Client.serialize_value(service[:endpoint])
|
873
|
+
buffer << service[:query].to_s_ggp
|
874
|
+
end
|
875
|
+
end
|
876
|
+
|
799
877
|
if options[:values]
|
800
878
|
vars = options[:values].first.map {|var| SPARQL::Client.serialize_value(var)}
|
801
879
|
buffer << "VALUES (#{vars.join(' ')}) {"
|
data/lib/sparql/client.rb
CHANGED
@@ -116,7 +116,14 @@ module SPARQL
|
|
116
116
|
# Close the http connection when object is deallocated
|
117
117
|
def self.finalize(klass)
|
118
118
|
proc do
|
119
|
-
|
119
|
+
if klass.respond_to?(:shutdown)
|
120
|
+
begin
|
121
|
+
# Attempt asynchronous shutdown
|
122
|
+
Thread.new {klass.shutdown}
|
123
|
+
rescue ThreadError
|
124
|
+
klass.shutdown
|
125
|
+
end
|
126
|
+
end
|
120
127
|
end
|
121
128
|
end
|
122
129
|
|
@@ -423,7 +430,13 @@ module SPARQL
|
|
423
430
|
end
|
424
431
|
RDF::Query::Solution.new(row)
|
425
432
|
end
|
426
|
-
RDF::Query::Solutions.new(solutions)
|
433
|
+
solns = RDF::Query::Solutions.new(solutions)
|
434
|
+
|
435
|
+
# Set variable names explicitly
|
436
|
+
if json.fetch('head', {}).has_key?('vars')
|
437
|
+
solns.variable_names = json['head']['vars'].map(&:to_sym)
|
438
|
+
end
|
439
|
+
solns
|
427
440
|
end
|
428
441
|
end
|
429
442
|
|
@@ -484,20 +497,23 @@ module SPARQL
|
|
484
497
|
vars = tsv.shift.map {|h| h.sub(/^\?/, '')}
|
485
498
|
solutions = RDF::Query::Solutions.new
|
486
499
|
tsv.each do |row|
|
500
|
+
# Flesh out columns which may be missing
|
501
|
+
vars.each_with_index do |_, i|
|
502
|
+
row[i] ||= ""
|
503
|
+
end
|
487
504
|
solution = RDF::Query::Solution.new
|
488
505
|
row.each_with_index do |v, i|
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
end
|
498
|
-
nodes[term.id] = term if term.is_a? RDF::Node
|
499
|
-
solution[vars[i].to_sym] = term
|
506
|
+
term = case v
|
507
|
+
when "" then RDF::Literal("")
|
508
|
+
when /^\d+\.\d*[eE][+-]?[0-9]+$/ then RDF::Literal::Double.new(v)
|
509
|
+
when /^\d*\.\d+[eE][+-]?[0-9]+$/ then RDF::Literal::Double.new(v)
|
510
|
+
when /^\d*\.\d+$/ then RDF::Literal::Decimal.new(v)
|
511
|
+
when /^\d+$/ then RDF::Literal::Integer.new(v)
|
512
|
+
else
|
513
|
+
RDF::NTriples.unserialize(v) || RDF::Literal(v)
|
500
514
|
end
|
515
|
+
nodes[term.id] = term if term.is_a? RDF::Node
|
516
|
+
solution[vars[i].to_sym] = term
|
501
517
|
end
|
502
518
|
solutions << solution
|
503
519
|
end
|
@@ -506,45 +522,57 @@ module SPARQL
|
|
506
522
|
|
507
523
|
##
|
508
524
|
# @param [String, IO, Nokogiri::XML::Node, REXML::Element] xml
|
525
|
+
# @param [Symbol] library (:nokogiri)
|
526
|
+
# One of :nokogiri or :rexml.
|
509
527
|
# @return [<RDF::Query::Solutions>]
|
510
528
|
# @see https://www.w3.org/TR/rdf-sparql-json-res/#results
|
511
|
-
def self.parse_xml_bindings(xml, nodes = {})
|
529
|
+
def self.parse_xml_bindings(xml, nodes = {}, library: :nokogiri)
|
512
530
|
xml.force_encoding(::Encoding::UTF_8) if xml.respond_to?(:force_encoding)
|
513
531
|
|
514
|
-
if defined?(::Nokogiri)
|
532
|
+
if defined?(::Nokogiri) && library == :nokogiri
|
515
533
|
xml = Nokogiri::XML(xml).root unless xml.is_a?(Nokogiri::XML::Document)
|
516
534
|
case
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
end
|
527
|
-
RDF::Query::Solution.new(row)
|
535
|
+
when boolean = xml.xpath("//sparql:boolean", XMLNS)[0]
|
536
|
+
boolean.text == 'true'
|
537
|
+
when results = xml.xpath("//sparql:results", XMLNS)[0]
|
538
|
+
solutions = results.elements.map do |result|
|
539
|
+
row = {}
|
540
|
+
result.elements.each do |binding|
|
541
|
+
name = binding.attr('name').to_sym
|
542
|
+
value = binding.elements.first
|
543
|
+
row[name] = parse_xml_value(value, nodes) if value
|
528
544
|
end
|
529
|
-
RDF::Query::
|
545
|
+
RDF::Query::Solution.new(row)
|
546
|
+
end
|
547
|
+
solns = RDF::Query::Solutions.new(solutions)
|
548
|
+
|
549
|
+
# Set variable names explicitly
|
550
|
+
var_names = xml.xpath("//sparql:head/sparql:variable/@name", XMLNS)
|
551
|
+
solns.variable_names = var_names.map(&:to_s)
|
552
|
+
solns
|
530
553
|
end
|
531
554
|
else
|
532
555
|
# REXML
|
533
556
|
xml = REXML::Document.new(xml).root unless xml.is_a?(REXML::Element)
|
534
557
|
case
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
541
|
-
|
542
|
-
|
543
|
-
|
544
|
-
end
|
545
|
-
RDF::Query::Solution.new(row)
|
558
|
+
when boolean = xml.elements['boolean']
|
559
|
+
boolean.text == 'true'
|
560
|
+
when results = xml.elements['results']
|
561
|
+
solutions = results.elements.map do |result|
|
562
|
+
row = {}
|
563
|
+
result.elements.each do |binding|
|
564
|
+
name = binding.attributes['name'].to_sym
|
565
|
+
value = binding.select { |node| node.kind_of?(::REXML::Element) }.first
|
566
|
+
row[name] = parse_xml_value(value, nodes) if value
|
546
567
|
end
|
547
|
-
RDF::Query::
|
568
|
+
RDF::Query::Solution.new(row)
|
569
|
+
end
|
570
|
+
solns = RDF::Query::Solutions.new(solutions)
|
571
|
+
|
572
|
+
# Set variable names explicitly
|
573
|
+
var_names = xml.elements['head'].elements.map {|e| e.attributes['name']}
|
574
|
+
solns.variable_names = var_names.map(&:to_sym)
|
575
|
+
solns
|
548
576
|
end
|
549
577
|
end
|
550
578
|
end
|
@@ -578,7 +606,7 @@ module SPARQL
|
|
578
606
|
# @return [RDF::Enumerable]
|
579
607
|
def parse_rdf_serialization(response, **options)
|
580
608
|
options = {content_type: response.content_type} unless options[:content_type]
|
581
|
-
if reader = RDF::Reader.for(options)
|
609
|
+
if reader = RDF::Reader.for(**options)
|
582
610
|
reader.new(response.body)
|
583
611
|
else
|
584
612
|
raise RDF::ReaderError, "no RDF reader was found for #{options}."
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sparql-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.2.
|
4
|
+
version: 3.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Arto Bendiken
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date:
|
13
|
+
date: 2023-07-23 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rdf
|
@@ -19,6 +19,9 @@ dependencies:
|
|
19
19
|
- - "~>"
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: '3.2'
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 3.2.11
|
22
25
|
type: :runtime
|
23
26
|
prerelease: false
|
24
27
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -26,6 +29,9 @@ dependencies:
|
|
26
29
|
- - "~>"
|
27
30
|
- !ruby/object:Gem::Version
|
28
31
|
version: '3.2'
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: 3.2.11
|
29
35
|
- !ruby/object:Gem::Dependency
|
30
36
|
name: net-http-persistent
|
31
37
|
requirement: !ruby/object:Gem::Requirement
|
@@ -35,7 +41,7 @@ dependencies:
|
|
35
41
|
version: '4.0'
|
36
42
|
- - ">="
|
37
43
|
- !ruby/object:Gem::Version
|
38
|
-
version: 4.0.
|
44
|
+
version: 4.0.2
|
39
45
|
type: :runtime
|
40
46
|
prerelease: false
|
41
47
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -45,7 +51,7 @@ dependencies:
|
|
45
51
|
version: '4.0'
|
46
52
|
- - ">="
|
47
53
|
- !ruby/object:Gem::Version
|
48
|
-
version: 4.0.
|
54
|
+
version: 4.0.2
|
49
55
|
- !ruby/object:Gem::Dependency
|
50
56
|
name: rdf-spec
|
51
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,14 +86,14 @@ dependencies:
|
|
80
86
|
requirements:
|
81
87
|
- - "~>"
|
82
88
|
- !ruby/object:Gem::Version
|
83
|
-
version: '3.
|
89
|
+
version: '3.12'
|
84
90
|
type: :development
|
85
91
|
prerelease: false
|
86
92
|
version_requirements: !ruby/object:Gem::Requirement
|
87
93
|
requirements:
|
88
94
|
- - "~>"
|
89
95
|
- !ruby/object:Gem::Version
|
90
|
-
version: '3.
|
96
|
+
version: '3.12'
|
91
97
|
- !ruby/object:Gem::Dependency
|
92
98
|
name: rspec-its
|
93
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -150,10 +156,15 @@ files:
|
|
150
156
|
- lib/sparql/client/repository.rb
|
151
157
|
- lib/sparql/client/update.rb
|
152
158
|
- lib/sparql/client/version.rb
|
153
|
-
homepage: https://github.com/ruby-rdf/sparql-client
|
159
|
+
homepage: https://github.com/ruby-rdf/sparql-client
|
154
160
|
licenses:
|
155
161
|
- Unlicense
|
156
|
-
metadata:
|
162
|
+
metadata:
|
163
|
+
documentation_uri: https://ruby-rdf.github.io/sparql-client
|
164
|
+
bug_tracker_uri: https://github.com/ruby-rdf/sparql-client/issues
|
165
|
+
homepage_uri: https://github.com/ruby-rdf/sparql-client
|
166
|
+
mailing_list_uri: https://lists.w3.org/Archives/Public/public-rdf-ruby/
|
167
|
+
source_code_uri: https://github.com/ruby-rdf/sparql-client
|
157
168
|
post_install_message:
|
158
169
|
rdoc_options: []
|
159
170
|
require_paths:
|
@@ -169,7 +180,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
180
|
- !ruby/object:Gem::Version
|
170
181
|
version: '0'
|
171
182
|
requirements: []
|
172
|
-
rubygems_version: 3.3.
|
183
|
+
rubygems_version: 3.3.26
|
173
184
|
signing_key:
|
174
185
|
specification_version: 4
|
175
186
|
summary: SPARQL client for RDF.rb.
|