sparql-client 3.1.1 → 3.2.1

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.
Files changed (5) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +13 -13
  3. data/VERSION +1 -1
  4. data/lib/sparql/client.rb +85 -40
  5. metadata +31 -14
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b464200c11f2c711f8fae5cb6d75a2deea216a2d682246b7b74ba8316c515404
4
- data.tar.gz: 63822682605b809841d008beee3599c81caa72df9d6d7c1004f9e7e1f136ed34
3
+ metadata.gz: cfca146902f11c4799f6b955e97deecf31873afc3c05309234cab948f34afd0c
4
+ data.tar.gz: 63cbaafab09deeddf3cbbcb23fe013c27ff82b759fa681a32219eebf24a771ba
5
5
  SHA512:
6
- metadata.gz: da4608ed0bc2c17af4bc7eba4c9c82f0be8095174fb18e8ec455441622a7efd3782e375f85eb8200b51617472fa0a6a94d0c7352e21e00e07dc21b1ec2709e23
7
- data.tar.gz: 1c78bbf4de5d7c6a30126938813991175598084ef19ebd38b3bd20d941ea8ab1b94cc347f3a7a1a2d7238745c2589ef173974e300edbb581f53e072c9b637724
6
+ metadata.gz: 3aa86e2182d70ab4ca0472c2ae4f5a6c645a95a848dbb6f74f38c4406c298e15a8e704d321d42b3d5a8186f607dcf5ad1304755a575e75e295ce81fa26eecdd8
7
+ data.tar.gz: 495bd5bcfed2a73e47c0a890ccce100551befd249216328209f0bf20a920a6d8db1efb6e4691172adbae7aeff58496bf5434f875987f61f7d2c0068116b762b5
data/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  This is a [Ruby][] implementation of a [SPARQL][] client for [RDF.rb][].
4
4
 
5
- * <https://ruby-rdf.github.com/sparql-client/>
5
+ * <https://ruby-rdf.github.io/sparql-client/>
6
6
 
7
7
  [![Gem Version](https://badge.fury.io/rb/sparql-client.png)](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)
@@ -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", { graph: "http://dbpedia.org" })
47
+ sparql = SPARQL::Client.new("http://dbpedia.org/sparql", graph: "http://dbpedia.org")
48
48
  ```
49
49
 
50
50
 
@@ -117,18 +117,18 @@ sparql.delete_data(data)
117
117
 
118
118
  ## Documentation
119
119
 
120
- * [SPARQL::Client](https://www.rubydoc.info/github/ruby-rdf/sparql-client/SPARQL/Client)
121
- * [SPARQL::Client::Query](https://www.rubydoc.info/github/ruby-rdf/sparql-client/SPARQL/Client/Query)
122
- * [SPARQL::Client::Repository](https://www.rubydoc.info/github/ruby-rdf/sparql-client/SPARQL/Client/Repository)
123
- * [SPARQL::Client::Update](https://www.rubydoc.info/github/ruby-rdf/sparql-client/SPARQL/Client/Update)
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
 
127
- * [Ruby](https://ruby-lang.org/) (>= 2.4)
128
- * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.1)
129
- * [Net::HTTP::Persistent](https://rubygems.org/gems/net-http-persistent) (~> 3.1)
130
- * Soft dependency on [SPARQL](https://rubygems.org/gems/sparql) (~> 3.1)
131
- * Soft dependency on [Nokogiri](https://rubygems.org/gems/nokogiri) (>= 1.10)
127
+ * [Ruby](https://ruby-lang.org/) (>= 2.6)
128
+ * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.2)
129
+ * [Net::HTTP::Persistent](https://rubygems.org/gems/net-http-persistent) (~> 4.0, >= 4.0.1)
130
+ * Soft dependency on [SPARQL](https://rubygems.org/gems/sparql) (~> 3.2)
131
+ * Soft dependency on [Nokogiri](https://rubygems.org/gems/nokogiri) (>= 1.12)
132
132
 
133
133
  ## Installation
134
134
 
@@ -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.com/sparql-client/>
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://rubydoc.info/github/ruby-rdf/rdf/RDF/Repository
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.1.1
1
+ 3.2.1
data/lib/sparql/client.rb CHANGED
@@ -102,7 +102,7 @@ module SPARQL
102
102
  @http = http_klass(@url.scheme)
103
103
 
104
104
  # Close the http connection when object is deallocated
105
- ObjectSpace.define_finalizer(self, proc {@http.shutdown if @http.respond_to?(:shutdown)})
105
+ ObjectSpace.define_finalizer(self, self.class.finalize(@http))
106
106
  end
107
107
 
108
108
  if block_given?
@@ -113,6 +113,20 @@ module SPARQL
113
113
  end
114
114
  end
115
115
 
116
+ # Close the http connection when object is deallocated
117
+ def self.finalize(klass)
118
+ proc do
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
127
+ end
128
+ end
129
+
116
130
  ##
117
131
  # Closes a client instance by finishing the connection.
118
132
  # 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.
@@ -416,7 +430,13 @@ module SPARQL
416
430
  end
417
431
  RDF::Query::Solution.new(row)
418
432
  end
419
- 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
420
440
  end
421
441
  end
422
442
 
@@ -435,6 +455,11 @@ module SPARQL
435
455
  RDF::Literal.new(value['value'], datatype: value['datatype'], language: value['xml:lang'])
436
456
  when :'typed-literal'
437
457
  RDF::Literal.new(value['value'], datatype: value['datatype'])
458
+ when :triple
459
+ s = parse_json_value(value['value']['subject'], nodes)
460
+ p = parse_json_value(value['value']['predicate'], nodes)
461
+ o = parse_json_value(value['value']['object'], nodes)
462
+ RDF::Statement(s, p, o)
438
463
  else nil
439
464
  end
440
465
  end
@@ -472,20 +497,23 @@ module SPARQL
472
497
  vars = tsv.shift.map {|h| h.sub(/^\?/, '')}
473
498
  solutions = RDF::Query::Solutions.new
474
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
475
504
  solution = RDF::Query::Solution.new
476
505
  row.each_with_index do |v, i|
477
- if !v.empty?
478
- term = RDF::NTriples.unserialize(v) || case v
479
- when /^\d+\.\d*[eE][+-]?[0-9]+$/ then RDF::Literal::Double.new(v)
480
- when /^\d*\.\d+[eE][+-]?[0-9]+$/ then RDF::Literal::Double.new(v)
481
- when /^\d*\.\d+$/ then RDF::Literal::Decimal.new(v)
482
- when /^\d+$/ then RDF::Literal::Integer.new(v)
483
- else
484
- RDF::Literal(v)
485
- end
486
- nodes[term.id] = term if term.is_a? RDF::Node
487
- 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)
488
514
  end
515
+ nodes[term.id] = term if term.is_a? RDF::Node
516
+ solution[vars[i].to_sym] = term
489
517
  end
490
518
  solutions << solution
491
519
  end
@@ -494,45 +522,57 @@ module SPARQL
494
522
 
495
523
  ##
496
524
  # @param [String, IO, Nokogiri::XML::Node, REXML::Element] xml
525
+ # @param [Symbol] library (:nokogiri)
526
+ # One of :nokogiri or :rexml.
497
527
  # @return [<RDF::Query::Solutions>]
498
528
  # @see https://www.w3.org/TR/rdf-sparql-json-res/#results
499
- def self.parse_xml_bindings(xml, nodes = {})
529
+ def self.parse_xml_bindings(xml, nodes = {}, library: :nokogiri)
500
530
  xml.force_encoding(::Encoding::UTF_8) if xml.respond_to?(:force_encoding)
501
531
 
502
- if defined?(::Nokogiri)
532
+ if defined?(::Nokogiri) && library == :nokogiri
503
533
  xml = Nokogiri::XML(xml).root unless xml.is_a?(Nokogiri::XML::Document)
504
534
  case
505
- when boolean = xml.xpath("//sparql:boolean", XMLNS)[0]
506
- boolean.text == 'true'
507
- when results = xml.xpath("//sparql:results", XMLNS)[0]
508
- solutions = results.elements.map do |result|
509
- row = {}
510
- result.elements.each do |binding|
511
- name = binding.attr('name').to_sym
512
- value = binding.elements.first
513
- row[name] = parse_xml_value(value, nodes)
514
- end
515
- 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)
516
544
  end
517
- RDF::Query::Solutions.new(solutions)
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
518
553
  end
519
554
  else
520
555
  # REXML
521
556
  xml = REXML::Document.new(xml).root unless xml.is_a?(REXML::Element)
522
557
  case
523
- when boolean = xml.elements['boolean']
524
- boolean.text == 'true'
525
- when results = xml.elements['results']
526
- solutions = results.elements.map do |result|
527
- row = {}
528
- result.elements.each do |binding|
529
- name = binding.attributes['name'].to_sym
530
- value = binding.select { |node| node.kind_of?(::REXML::Element) }.first
531
- row[name] = parse_xml_value(value, nodes)
532
- end
533
- 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)
534
567
  end
535
- RDF::Query::Solutions.new(solutions)
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
536
576
  end
537
577
  end
538
578
  end
@@ -551,6 +591,11 @@ module SPARQL
551
591
  lang = value.respond_to?(:attr) ? value.attr('xml:lang') : value.attributes['xml:lang']
552
592
  datatype = value.respond_to?(:attr) ? value.attr('datatype') : value.attributes['datatype']
553
593
  RDF::Literal.new(value.text, language: lang, datatype: datatype)
594
+ when :triple
595
+ # Note, this is order dependent
596
+ res = value.elements.map {|e| e.elements.to_a}.
597
+ flatten.map {|e| parse_xml_value(e, nodes)}
598
+ RDF::Statement(*res)
554
599
  else nil
555
600
  end
556
601
  end
@@ -561,7 +606,7 @@ module SPARQL
561
606
  # @return [RDF::Enumerable]
562
607
  def parse_rdf_serialization(response, **options)
563
608
  options = {content_type: response.content_type} unless options[:content_type]
564
- if reader = RDF::Reader.for(options)
609
+ if reader = RDF::Reader.for(**options)
565
610
  reader.new(response.body)
566
611
  else
567
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.1.1
4
+ version: 3.2.1
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: 2020-12-25 00:00:00.000000000 Z
13
+ date: 2022-03-16 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rdf
@@ -18,14 +18,20 @@ dependencies:
18
18
  requirements:
19
19
  - - "~>"
20
20
  - !ruby/object:Gem::Version
21
- version: '3.1'
21
+ version: '3.2'
22
+ - - ">="
23
+ - !ruby/object:Gem::Version
24
+ version: 3.2.6
22
25
  type: :runtime
23
26
  prerelease: false
24
27
  version_requirements: !ruby/object:Gem::Requirement
25
28
  requirements:
26
29
  - - "~>"
27
30
  - !ruby/object:Gem::Version
28
- version: '3.1'
31
+ version: '3.2'
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: 3.2.6
29
35
  - !ruby/object:Gem::Dependency
30
36
  name: net-http-persistent
31
37
  requirement: !ruby/object:Gem::Requirement
@@ -33,6 +39,9 @@ dependencies:
33
39
  - - "~>"
34
40
  - !ruby/object:Gem::Version
35
41
  version: '4.0'
42
+ - - ">="
43
+ - !ruby/object:Gem::Version
44
+ version: 4.0.1
36
45
  type: :runtime
37
46
  prerelease: false
38
47
  version_requirements: !ruby/object:Gem::Requirement
@@ -40,34 +49,37 @@ dependencies:
40
49
  - - "~>"
41
50
  - !ruby/object:Gem::Version
42
51
  version: '4.0'
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 4.0.1
43
55
  - !ruby/object:Gem::Dependency
44
56
  name: rdf-spec
45
57
  requirement: !ruby/object:Gem::Requirement
46
58
  requirements:
47
59
  - - "~>"
48
60
  - !ruby/object:Gem::Version
49
- version: '3.1'
61
+ version: '3.2'
50
62
  type: :development
51
63
  prerelease: false
52
64
  version_requirements: !ruby/object:Gem::Requirement
53
65
  requirements:
54
66
  - - "~>"
55
67
  - !ruby/object:Gem::Version
56
- version: '3.1'
68
+ version: '3.2'
57
69
  - !ruby/object:Gem::Dependency
58
70
  name: sparql
59
71
  requirement: !ruby/object:Gem::Requirement
60
72
  requirements:
61
73
  - - "~>"
62
74
  - !ruby/object:Gem::Version
63
- version: '3.1'
75
+ version: '3.2'
64
76
  type: :development
65
77
  prerelease: false
66
78
  version_requirements: !ruby/object:Gem::Requirement
67
79
  requirements:
68
80
  - - "~>"
69
81
  - !ruby/object:Gem::Version
70
- version: '3.1'
82
+ version: '3.2'
71
83
  - !ruby/object:Gem::Dependency
72
84
  name: rspec
73
85
  requirement: !ruby/object:Gem::Requirement
@@ -102,14 +114,14 @@ dependencies:
102
114
  requirements:
103
115
  - - "~>"
104
116
  - !ruby/object:Gem::Version
105
- version: '3.11'
117
+ version: '3.14'
106
118
  type: :development
107
119
  prerelease: false
108
120
  version_requirements: !ruby/object:Gem::Requirement
109
121
  requirements:
110
122
  - - "~>"
111
123
  - !ruby/object:Gem::Version
112
- version: '3.11'
124
+ version: '3.14'
113
125
  - !ruby/object:Gem::Dependency
114
126
  name: yard
115
127
  requirement: !ruby/object:Gem::Requirement
@@ -144,10 +156,15 @@ files:
144
156
  - lib/sparql/client/repository.rb
145
157
  - lib/sparql/client/update.rb
146
158
  - lib/sparql/client/version.rb
147
- homepage: https://github.com/ruby-rdf/sparql-client/
159
+ homepage: https://github.com/ruby-rdf/sparql-client
148
160
  licenses:
149
161
  - Unlicense
150
- 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
151
168
  post_install_message:
152
169
  rdoc_options: []
153
170
  require_paths:
@@ -156,14 +173,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
156
173
  requirements:
157
174
  - - ">="
158
175
  - !ruby/object:Gem::Version
159
- version: '2.4'
176
+ version: '2.6'
160
177
  required_rubygems_version: !ruby/object:Gem::Requirement
161
178
  requirements:
162
179
  - - ">="
163
180
  - !ruby/object:Gem::Version
164
181
  version: '0'
165
182
  requirements: []
166
- rubygems_version: 3.1.4
183
+ rubygems_version: 3.3.3
167
184
  signing_key:
168
185
  specification_version: 4
169
186
  summary: SPARQL client for RDF.rb.