sparql-client 3.2.0 → 3.2.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 +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
|
-
[](https://badge.fury.io/rb/sparql-client)
|
8
8
|
[](https://github.com/ruby-rdf/sparql-client/actions?query=workflow%3ACI)
|
9
9
|
[](https://coveralls.io/github/ruby-rdf/sparql-client?branch=master)
|
10
10
|
[](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.
|