sparql 3.1.8 → 3.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (139) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +29 -22
  3. data/VERSION +1 -1
  4. data/bin/sparql +13 -4
  5. data/lib/sparql/algebra/extensions.rb +93 -33
  6. data/lib/sparql/algebra/operator/abs.rb +22 -2
  7. data/lib/sparql/algebra/operator/add.rb +21 -2
  8. data/lib/sparql/algebra/operator/alt.rb +26 -2
  9. data/lib/sparql/algebra/operator/and.rb +25 -3
  10. data/lib/sparql/algebra/operator/asc.rb +20 -1
  11. data/lib/sparql/algebra/operator/ask.rb +17 -1
  12. data/lib/sparql/algebra/operator/avg.rb +17 -1
  13. data/lib/sparql/algebra/operator/base.rb +18 -1
  14. data/lib/sparql/algebra/operator/bgp.rb +5 -1
  15. data/lib/sparql/algebra/operator/bnode.rb +33 -10
  16. data/lib/sparql/algebra/operator/bound.rb +22 -1
  17. data/lib/sparql/algebra/operator/ceil.rb +25 -2
  18. data/lib/sparql/algebra/operator/clear.rb +16 -2
  19. data/lib/sparql/algebra/operator/coalesce.rb +33 -11
  20. data/lib/sparql/algebra/operator/compare.rb +9 -0
  21. data/lib/sparql/algebra/operator/concat.rb +26 -2
  22. data/lib/sparql/algebra/operator/construct.rb +29 -6
  23. data/lib/sparql/algebra/operator/contains.rb +24 -2
  24. data/lib/sparql/algebra/operator/copy.rb +19 -2
  25. data/lib/sparql/algebra/operator/count.rb +17 -1
  26. data/lib/sparql/algebra/operator/create.rb +19 -2
  27. data/lib/sparql/algebra/operator/dataset.rb +17 -0
  28. data/lib/sparql/algebra/operator/datatype.rb +25 -6
  29. data/lib/sparql/algebra/operator/day.rb +23 -5
  30. data/lib/sparql/algebra/operator/delete.rb +27 -2
  31. data/lib/sparql/algebra/operator/delete_data.rb +23 -2
  32. data/lib/sparql/algebra/operator/delete_where.rb +24 -2
  33. data/lib/sparql/algebra/operator/desc.rb +20 -1
  34. data/lib/sparql/algebra/operator/describe.rb +27 -4
  35. data/lib/sparql/algebra/operator/distinct.rb +18 -1
  36. data/lib/sparql/algebra/operator/divide.rb +26 -2
  37. data/lib/sparql/algebra/operator/drop.rb +17 -2
  38. data/lib/sparql/algebra/operator/encode_for_uri.rb +24 -2
  39. data/lib/sparql/algebra/operator/equal.rb +12 -2
  40. data/lib/sparql/algebra/operator/exists.rb +28 -4
  41. data/lib/sparql/algebra/operator/exprlist.rb +12 -1
  42. data/lib/sparql/algebra/operator/extend.rb +31 -6
  43. data/lib/sparql/algebra/operator/filter.rb +27 -5
  44. data/lib/sparql/algebra/operator/floor.rb +25 -2
  45. data/lib/sparql/algebra/operator/graph.rb +13 -0
  46. data/lib/sparql/algebra/operator/greater_than.rb +12 -3
  47. data/lib/sparql/algebra/operator/greater_than_or_equal.rb +12 -2
  48. data/lib/sparql/algebra/operator/group.rb +34 -8
  49. data/lib/sparql/algebra/operator/group_concat.rb +19 -7
  50. data/lib/sparql/algebra/operator/hours.rb +23 -5
  51. data/lib/sparql/algebra/operator/if.rb +21 -4
  52. data/lib/sparql/algebra/operator/in.rb +18 -1
  53. data/lib/sparql/algebra/operator/insert.rb +22 -2
  54. data/lib/sparql/algebra/operator/insert_data.rb +23 -2
  55. data/lib/sparql/algebra/operator/iri.rb +21 -4
  56. data/lib/sparql/algebra/operator/is_blank.rb +19 -1
  57. data/lib/sparql/algebra/operator/is_iri.rb +19 -1
  58. data/lib/sparql/algebra/operator/is_literal.rb +19 -1
  59. data/lib/sparql/algebra/operator/is_numeric.rb +21 -3
  60. data/lib/sparql/algebra/operator/is_triple.rb +32 -0
  61. data/lib/sparql/algebra/operator/join.rb +22 -1
  62. data/lib/sparql/algebra/operator/lang.rb +25 -0
  63. data/lib/sparql/algebra/operator/lang_matches.rb +22 -1
  64. data/lib/sparql/algebra/operator/lcase.rb +23 -2
  65. data/lib/sparql/algebra/operator/left_join.rb +29 -1
  66. data/lib/sparql/algebra/operator/less_than.rb +12 -3
  67. data/lib/sparql/algebra/operator/less_than_or_equal.rb +12 -2
  68. data/lib/sparql/algebra/operator/load.rb +25 -2
  69. data/lib/sparql/algebra/operator/max.rb +17 -1
  70. data/lib/sparql/algebra/operator/md5.rb +22 -5
  71. data/lib/sparql/algebra/operator/min.rb +18 -2
  72. data/lib/sparql/algebra/operator/minus.rb +25 -7
  73. data/lib/sparql/algebra/operator/minutes.rb +23 -5
  74. data/lib/sparql/algebra/operator/modify.rb +41 -5
  75. data/lib/sparql/algebra/operator/month.rb +23 -5
  76. data/lib/sparql/algebra/operator/move.rb +20 -2
  77. data/lib/sparql/algebra/operator/multiply.rb +26 -3
  78. data/lib/sparql/algebra/operator/negate.rb +23 -3
  79. data/lib/sparql/algebra/operator/not.rb +24 -3
  80. data/lib/sparql/algebra/operator/not_equal.rb +13 -0
  81. data/lib/sparql/algebra/operator/notexists.rb +30 -6
  82. data/lib/sparql/algebra/operator/notin.rb +20 -3
  83. data/lib/sparql/algebra/operator/notoneof.rb +12 -2
  84. data/lib/sparql/algebra/operator/now.rb +24 -5
  85. data/lib/sparql/algebra/operator/object.rb +32 -0
  86. data/lib/sparql/algebra/operator/or.rb +26 -3
  87. data/lib/sparql/algebra/operator/order.rb +20 -1
  88. data/lib/sparql/algebra/operator/path.rb +29 -2
  89. data/lib/sparql/algebra/operator/path_opt.rb +21 -2
  90. data/lib/sparql/algebra/operator/path_plus.rb +21 -2
  91. data/lib/sparql/algebra/operator/path_star.rb +20 -2
  92. data/lib/sparql/algebra/operator/plus.rb +42 -3
  93. data/lib/sparql/algebra/operator/predicate.rb +32 -0
  94. data/lib/sparql/algebra/operator/prefix.rb +24 -3
  95. data/lib/sparql/algebra/operator/project.rb +51 -5
  96. data/lib/sparql/algebra/operator/rand.rb +30 -2
  97. data/lib/sparql/algebra/operator/reduced.rb +18 -1
  98. data/lib/sparql/algebra/operator/regex.rb +26 -18
  99. data/lib/sparql/algebra/operator/replace.rb +26 -6
  100. data/lib/sparql/algebra/operator/reverse.rb +20 -2
  101. data/lib/sparql/algebra/operator/round.rb +25 -2
  102. data/lib/sparql/algebra/operator/same_term.rb +24 -6
  103. data/lib/sparql/algebra/operator/sample.rb +30 -8
  104. data/lib/sparql/algebra/operator/seconds.rb +23 -5
  105. data/lib/sparql/algebra/operator/seq.rb +20 -2
  106. data/lib/sparql/algebra/operator/sequence.rb +0 -10
  107. data/lib/sparql/algebra/operator/sha1.rb +18 -1
  108. data/lib/sparql/algebra/operator/sha256.rb +18 -1
  109. data/lib/sparql/algebra/operator/sha384.rb +18 -1
  110. data/lib/sparql/algebra/operator/sha512.rb +18 -1
  111. data/lib/sparql/algebra/operator/slice.rb +27 -5
  112. data/lib/sparql/algebra/operator/str.rb +21 -1
  113. data/lib/sparql/algebra/operator/strafter.rb +25 -2
  114. data/lib/sparql/algebra/operator/strbefore.rb +25 -2
  115. data/lib/sparql/algebra/operator/strdt.rb +22 -1
  116. data/lib/sparql/algebra/operator/strends.rb +25 -3
  117. data/lib/sparql/algebra/operator/strlang.rb +25 -6
  118. data/lib/sparql/algebra/operator/strlen.rb +23 -2
  119. data/lib/sparql/algebra/operator/strstarts.rb +25 -2
  120. data/lib/sparql/algebra/operator/struuid.rb +29 -9
  121. data/lib/sparql/algebra/operator/subject.rb +32 -0
  122. data/lib/sparql/algebra/operator/substr.rb +23 -2
  123. data/lib/sparql/algebra/operator/subtract.rb +28 -2
  124. data/lib/sparql/algebra/operator/sum.rb +17 -1
  125. data/lib/sparql/algebra/operator/table.rb +42 -4
  126. data/lib/sparql/algebra/operator/timezone.rb +23 -5
  127. data/lib/sparql/algebra/operator/tz.rb +22 -5
  128. data/lib/sparql/algebra/operator/ucase.rb +23 -2
  129. data/lib/sparql/algebra/operator/union.rb +29 -6
  130. data/lib/sparql/algebra/operator/update.rb +25 -4
  131. data/lib/sparql/algebra/operator/using.rb +32 -2
  132. data/lib/sparql/algebra/operator/uuid.rb +27 -8
  133. data/lib/sparql/algebra/operator/with.rb +38 -4
  134. data/lib/sparql/algebra/operator/year.rb +23 -5
  135. data/lib/sparql/algebra/operator.rb +99 -6
  136. data/lib/sparql/algebra/sxp_extensions.rb +3 -3
  137. data/lib/sparql/grammar/parser11.rb +4 -4
  138. metadata +22 -35
  139. data/lib/sparql/algebra/operator/triple.rb +0 -27
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0fc6d6745c325bd23d83fe640eb238a22406b567cf06223703afd90ea5733be1
4
- data.tar.gz: 056cde1c14633aa791f492be673eb023bab95d7af4e5b19fb94c99540fc22908
3
+ metadata.gz: ecbe9289bf43f7fa28940a82545ec08b19c54d8bdf64693934405e83ddb4cc53
4
+ data.tar.gz: 24ab0942be18a9d9d281452ba9a7195dcad2a31755bda6d84afe4f49fe7c34c1
5
5
  SHA512:
6
- metadata.gz: 32187664d7d06bd49cffa8354987ce3f11ba44b35960a92ac80353a538a15489b342f1d3e66a0ad792971489e83cc57ab05b936e93f8e04fe2f5df4a527d3d39
7
- data.tar.gz: 9d8a75fd40c9ccbac6a9753d9b7a04b9e26a4504a55636d61d3d34c1d4dde77c6838d5ac45828a40d06b7c4658971c1f435da0c6812e7b2eda4aa5dfcfaa9cda
6
+ metadata.gz: 89a77c749eb99b0fe83f27d5f413556ac2f6cf22af7e06b8e0588155bbf5a50eb053b1f87ffe11a13b5fd873d5fcaaee1166cdf336aacd3029380898a82da382
7
+ data.tar.gz: 13be95c405b9fdf7e678bc9bbaf6dcc45075a692a08e1762deacc0779948996fdc992376f3a564644f50270282c76a759023d7393e28db07ec7828a73324a948
data/README.md CHANGED
@@ -23,8 +23,7 @@ This is a [Ruby][] implementation of [SPARQL][] for [RDF.rb][].
23
23
  * Compatible with any [Rack][] or [Sinatra][] application and any Rack-based framework.
24
24
  * Helper method for describing [SPARQL Service Description][SSD]
25
25
  * Implementation Report: {file:etc/earl.html EARL}
26
- * Compatible with Ruby >= 2.2.2.
27
- * Compatible with older Ruby versions with the help of the [Backports][] gem.
26
+ * Compatible with Ruby >= 2.6.
28
27
  * Supports Unicode query strings both on all versions of Ruby.
29
28
  * Provisional support for [SPARQL-star][].
30
29
 
@@ -248,27 +247,27 @@ a full set of RDF formats.
248
247
  ### Querying a repository with a SPARQL query
249
248
 
250
249
  queryable = RDF::Repository.load("etc/doap.ttl")
251
- sse = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
252
- queryable.query(sse) do |result|
250
+ query = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
251
+ queryable.query(query) do |result|
253
252
  result.inspect
254
253
  end
255
254
 
256
255
  ### Executing a SPARQL query against a repository
257
256
 
258
257
  queryable = RDF::Repository.load("etc/doap.ttl")
259
- sse = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
260
- sse.execute(queryable) do |result|
258
+ query = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
259
+ query.execute(queryable) do |result|
261
260
  result.inspect
262
261
  end
263
262
 
264
263
  ### Updating a repository
265
264
 
266
265
  queryable = RDF::Repository.load("etc/doap.ttl")
267
- sse = SPARQL.parse(%(
266
+ update = SPARQL.parse(%(
268
267
  PREFIX doap: <http://usefulinc.com/ns/doap#>
269
268
  INSERT DATA { <https://rubygems> doap:implements <http://www.w3.org/TR/sparql11-update/>}
270
269
  ), update: true)
271
- sse.execute(queryable)
270
+ update.execute(queryable)
272
271
 
273
272
  ### Rendering solutions as JSON, XML, CSV, TSV or HTML
274
273
  queryable = RDF::Repository.load("etc/doap.ttl")
@@ -277,8 +276,13 @@ a full set of RDF formats.
277
276
 
278
277
  ### Parsing a SPARQL query string to SSE
279
278
 
280
- sse = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
281
- sse.to_sxp #=> (bgp (triple ?s ?p ?o))
279
+ query = SPARQL.parse("SELECT * WHERE { ?s ?p ?o }")
280
+ query.to_sxp #=> (bgp (triple ?s ?p ?o))
281
+
282
+ ### Parsing a SSE to SPARQL query or update string to SPARQL
283
+
284
+ query = SPARQL::Algebra.parse(%{(bgp (triple ?s ?p ?o))})
285
+ sparql = query.to_sparql #=> "SELECT * WHERE { ?s ?p ?o }"
282
286
 
283
287
  ### Command line processing
284
288
 
@@ -289,6 +293,10 @@ a full set of RDF formats.
289
293
  sparql parse etc/input.rq
290
294
  sparql parse -e "SELECT * WHERE { ?s ?p ?o }"
291
295
 
296
+ # Generate SPARQL Query from SSE
297
+ sparql parse --sse etc/input.sse --format sparql
298
+ sparql parse --sse --format sparql -e "(dataset (<http://usefulinc.com/ns/doap>) (bgp (triple ?s ?p ?o))))"
299
+
292
300
  # Run query using SSE input
293
301
  sparql execute --dataset etc/doap.ttl --sse etc/input.sse
294
302
  sparql execute --sse -e "(dataset (<etc/doap.ttl>) (bgp (triple ?s ?p ?o))))"
@@ -368,19 +376,19 @@ Full documentation available on [Rubydoc.info][SPARQL doc]
368
376
 
369
377
  ## Dependencies
370
378
 
371
- * [Ruby](https://ruby-lang.org/) (>= 2.2.2)
372
- * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.0)
373
- * [SPARQL::Client](https://rubygems.org/gems/sparql-client) (~> 3.0)
374
- * [SXP](https://rubygems.org/gems/sxp) (~> 1.0)
375
- * [Builder](https://rubygems.org/gems/builder) (>= 3.0.0)
376
- * [JSON](https://rubygems.org/gems/json) (>= 1.8.2)
377
- * Soft dependency on [Linked Data][] (>= 3.0)
378
- * Soft dependency on [Nokogiri](https://rubygems.org/gems/nokogiri) (>= 1.7)
379
+ * [Ruby](https://ruby-lang.org/) (>= 2.6)
380
+ * [RDF.rb](https://rubygems.org/gems/rdf) (~> 3.2)
381
+ * [SPARQL::Client](https://rubygems.org/gems/sparql-client) (~> 3.1)
382
+ * [SXP](https://rubygems.org/gems/sxp) (~> 1.2)
383
+ * [Builder](https://rubygems.org/gems/builder) (~> 3.2)
384
+ * [JSON](https://rubygems.org/gems/json) (~> 2.6)
385
+ * Soft dependency on [Linked Data][] (>= 3.1)
386
+ * Soft dependency on [Nokogiri](https://rubygems.org/gems/nokogiri) (~> 1.12)
379
387
  Falls back to REXML for XML parsing Builder for XML serializing. Nokogiri is much more efficient
380
- * Soft dependency on [Equivalent XML](https://rubygems.org/gems/equivalent-xml) (>= 0.3.0)
388
+ * Soft dependency on [Equivalent XML](https://rubygems.org/gems/equivalent-xml) (>= 0.6)
381
389
  Equivalent XML performs more efficient comparisons of XML Literals when Nokogiri is included
382
- * Soft dependency on [Rack][] (>= 2.0)
383
- * Soft dependency on [Sinatra][] (>= 2.0)
390
+ * Soft dependency on [Rack][] (~> 2.2)
391
+ * Soft dependency on [Sinatra][] (~> 2.1)
384
392
 
385
393
  ## Installation
386
394
 
@@ -450,7 +458,6 @@ A copy of the [SPARQL 1.0 tests][] and [SPARQL 1.1 tests][] are also included in
450
458
  [RDF.rb]: https://rubydoc.info/github/ruby-rdf/rdf
451
459
  [RDF-star]: https://w3c.github.io/rdf-star/rdf-star-cg-spec.html
452
460
  [SPARQL-star]: https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#sparql-query-language
453
- [Backports]: https://rubygems.org/gems/backports
454
461
  [Linked Data]: https://rubygems.org/gems/linkeddata
455
462
  [SPARQL doc]: https://rubydoc.info/github/ruby-rdf/sparql/frames
456
463
  [SPARQL XML]: https://www.w3.org/TR/rdf-sparql-XMLres/
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.8
1
+ 3.2.0
data/bin/sparql CHANGED
@@ -45,9 +45,18 @@ def run(input, **options)
45
45
  SPARQL::Grammar.parse(input, **options)
46
46
  end
47
47
 
48
- puts ("\nSSE:\n" + query.to_sse) if options[:debug] || options[:to_sse]
48
+ puts ("\nSSE:\n" + query.to_sse) if options[:debug]
49
49
 
50
- unless options[:to_sse]
50
+ if options[:parse_only]
51
+ case options[:format]
52
+ when :sparql
53
+ puts ("\nSPARQL:\n" + query.to_sparql)
54
+ when nil, :sse
55
+ puts ("\nSSE:\n" + query.to_sse)
56
+ else
57
+ $stderr.puts "Unknown output format for parsing: #{options[:format]}. Use 'sse' or 'sparql'"
58
+ end
59
+ else
51
60
  res = query.execute(options[:dataset], logger: options[:logger])
52
61
  display_results(res, **options)
53
62
  end
@@ -98,7 +107,7 @@ def usage
98
107
  puts " --dataset: File containing RDF graph or dataset"
99
108
  puts " --debug: Display detailed debug output"
100
109
  puts " --execute,-e: Use option argument as the SPARQL input if no query-file given"
101
- puts " --format: Output format for results"
110
+ puts " --format: Output format for results (json, xml, csv, tsv, html, sparql, sse, or another RDF format)"
102
111
  puts " --port,-p Port on which to run server; defaults to 9292"
103
112
  puts " --sse: Query input is in SSE format"
104
113
  puts " --update: Process query as a SPARQL Update"
@@ -151,7 +160,7 @@ end
151
160
 
152
161
  case cmd
153
162
  when 'execute', 'parse'
154
- options[:to_sse] = true if cmd == 'parse'
163
+ options[:parse_only] = true if cmd == 'parse'
155
164
  input ||= ARGV.empty? ? $stdin.read : RDF::Util::File.open_file(ARGV.first).read
156
165
  run(input, **options)
157
166
  when 'query'
@@ -43,6 +43,15 @@ class Object
43
43
  def deep_dup
44
44
  dup
45
45
  end
46
+
47
+ ##
48
+ #
49
+ # Returns a partial SPARQL grammar for this term.
50
+ #
51
+ # @return [String]
52
+ def to_sparql(**options)
53
+ to_sxp(**options)
54
+ end
46
55
  end
47
56
 
48
57
  ##
@@ -56,6 +65,16 @@ class Array
56
65
  map {|x| x.to_sxp_bin}
57
66
  end
58
67
 
68
+ ##
69
+ #
70
+ # Returns a partial SPARQL grammar for this array.
71
+ #
72
+ # @param [String] delimiter (" ")
73
+ # @return [String]
74
+ def to_sparql(delimiter: " ", **options)
75
+ map {|e| e.to_sparql(**options)}.join(delimiter)
76
+ end
77
+
59
78
  ##
60
79
  # Evaluates the array using the given variable `bindings`.
61
80
  #
@@ -216,15 +235,6 @@ end
216
235
  ##
217
236
  # Extensions for Ruby's `Hash` class.
218
237
  class Hash
219
- ##
220
- # Returns the SXP representation of this object, defaults to `self`.
221
- #
222
- # @return [String]
223
- def to_sxp_bin
224
- to_a.to_sxp_bin
225
- end
226
- def to_sxp; to_sxp_bin; end
227
-
228
238
  ##
229
239
  # A duplicate of this hash.
230
240
  #
@@ -278,24 +288,20 @@ module RDF::Term
278
288
  # @see SPARQL::Algebra::Expression#optimize
279
289
  def optimize(**options)
280
290
  optimized = self.deep_dup
281
- optimized.lexical = nil if optimized.respond_to?(:lexical=)
282
- optimized
291
+ #optimized.lexical = nil if optimized.respond_to?(:lexical=)
292
+ #optimized
283
293
  end
284
- end # RDF::Term
285
294
 
286
- class RDF::Literal::Double
287
295
  ##
288
- # Returns the SXP representation of this object.
296
+ #
297
+ # Returns a partial SPARQL grammar for this term.
289
298
  #
290
299
  # @return [String]
291
- def to_sxp
292
- case
293
- when nan? then 'nan.0'
294
- when infinite? then (infinite? > 0 ? '+inf.0' : '-inf.0')
295
- else canonicalize.to_s.downcase
296
- end
300
+ def to_sparql(**options)
301
+ to_sxp(**options)
297
302
  end
298
- end
303
+ end # RDF::Term
304
+
299
305
 
300
306
  # Override RDF::Queryable to execute against SPARQL::Algebra::Query elements as well as RDF::Query and RDF::Pattern
301
307
  module RDF::Queryable
@@ -343,6 +349,15 @@ module RDF::Queryable
343
349
  query_without_sparql(pattern, **options, &block)
344
350
  end
345
351
  end
352
+
353
+ ##
354
+ #
355
+ # Returns a partial SPARQL grammar for this term.
356
+ #
357
+ # @return [String]
358
+ def to_sparql(**options)
359
+ raise NotImplementedError, "SPARQL::Algebra '#{first}' operator not implemented"
360
+ end
346
361
  end
347
362
 
348
363
  class RDF::Statement
@@ -361,9 +376,29 @@ class RDF::Statement
361
376
  ##
362
377
  # Returns an S-Expression (SXP) representation
363
378
  #
379
+ # @param [Hash{Symbol => RDF::URI}] prefixes (nil)
380
+ # @param [RDF::URI] base_uri (nil)
364
381
  # @return [String]
365
- def to_sxp
366
- to_sxp_bin.to_sxp
382
+ def to_sxp(prefixes: nil, base_uri: nil)
383
+ to_sxp_bin.to_sxp(prefixes: prefixes, base_uri: base_uri)
384
+ end
385
+
386
+ ##
387
+ #
388
+ # Returns a partial SPARQL grammar for this term.
389
+ #
390
+ # @param [Boolean] as_statement (false) serialize as < ... >, otherwise TRIPLE(...)
391
+ # @return [String]
392
+ def to_sparql(as_statement: false, **options)
393
+ return "TRIPLE(#{to_triple.to_sparql(as_statement: true, **options)})" unless as_statement
394
+
395
+ to_triple.map do |term|
396
+ if term.is_a?(::RDF::Statement)
397
+ "<<" + term.to_sparql(**options) + ">>"
398
+ else
399
+ term.to_sparql(**options)
400
+ end
401
+ end.join(" ") + " ."
367
402
  end
368
403
 
369
404
  ##
@@ -411,6 +446,19 @@ class RDF::Query
411
446
  end
412
447
  end
413
448
 
449
+ ##
450
+ #
451
+ # Returns a partial SPARQL grammar for this term.
452
+ #
453
+ # @param [Boolean] top_level (true)
454
+ # Treat this as a top-level, generating SELECT ... WHERE {}
455
+ # @return [String]
456
+ def to_sparql(top_level: true, **options)
457
+ str = @patterns.map { |e| e.to_sparql(as_statement: true, top_level: false, **options) }.join("\n")
458
+ str = "GRAPH #{graph_name.to_sparql(**options)} {\n#{str}\n}\n" if graph_name
459
+ top_level ? SPARQL::Algebra::Operator.to_sparql(str, **options) : str
460
+ end
461
+
414
462
  ##
415
463
  # Binds the pattern to a solution, making it no longer variable if all variables are resolved to bound variables
416
464
  #
@@ -462,11 +510,11 @@ class RDF::Query
462
510
  def optimize!(**options)
463
511
  @patterns = @patterns.map do |pattern|
464
512
  components = pattern.to_quad.map do |term|
465
- if term.respond_to?(:lexical=)
466
- term.dup.instance_eval {@lexical = nil; self}
467
- else
513
+ #if term.respond_to?(:lexical=)
514
+ # term.dup.instance_eval {@lexical = nil; self}
515
+ #else
468
516
  term
469
- end
517
+ #end
470
518
  end
471
519
  RDF::Query::Pattern.from(components, **pattern.options)
472
520
  end
@@ -530,11 +578,15 @@ class RDF::Query::Variable
530
578
  self
531
579
  end
532
580
 
533
- # Display variable as SXP
534
- # @return [Array]
535
- def to_sxp
536
- prefix = distinguished? ? (existential? ? '$' : '?') : (existential? ? '$$' : '??')
537
- unbound? ? "#{prefix}#{name}".to_sym.to_sxp : ["#{prefix}#{name}".to_sym, value].to_sxp
581
+ ##
582
+ #
583
+ # Returns a partial SPARQL grammar for this term.
584
+ #
585
+ # The Non-distinguished form (`??xxx`) is not part of the grammar, so replace with a blank-node
586
+ #
587
+ # @return [String]
588
+ def to_sparql(**options)
589
+ self.distinguished? ? super : "_:_nd#{self.name}"
538
590
  end
539
591
  end # RDF::Query::Variable
540
592
 
@@ -576,5 +628,13 @@ class RDF::Query::Solution
576
628
  def to_sxp_bin
577
629
  to_a.to_sxp_bin
578
630
  end
579
- def to_sxp; to_sxp_bin; end
631
+
632
+ # Transform Solution into an SXP
633
+ #
634
+ # @param [Hash{Symbol => RDF::URI}] prefixes (nil)
635
+ # @param [RDF::URI] base_uri (nil)
636
+ # @return [String]
637
+ def to_sxp(prefixes: nil, base_uri: nil)
638
+ to_sxp_bin.to_sxp(prefixes: prefixes, base_uri: base_uri)
639
+ end
580
640
  end # RDF::Query::Solution
@@ -3,8 +3,19 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL logical `abs` operator.
5
5
  #
6
- # @example
7
- # (abs ?x)
6
+ # [121] BuiltInCall ::= ... | 'ABS' '(' Expression ')'
7
+ #
8
+ # @example SPARQL Query
9
+ # PREFIX : <http://example.org/>
10
+ # SELECT * WHERE {
11
+ # ?s :num ?num
12
+ # FILTER(ABS(?num) >= 2)
13
+ # }
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/>))
17
+ # (filter (>= (abs ?num) 2)
18
+ # (bgp (triple ?s :num ?num))))
8
19
  #
9
20
  # @see https://www.w3.org/TR/sparql11-query/#func-abs
10
21
  # @see https://www.w3.org/TR/xpath-functions/#func-abs
@@ -26,6 +37,15 @@ module SPARQL; module Algebra
26
37
  else raise TypeError, "expected an RDF::Literal::Numeric, but got #{operand.inspect}"
27
38
  end
28
39
  end
40
+
41
+ ##
42
+ #
43
+ # Returns a partial SPARQL grammar for this operator.
44
+ #
45
+ # @return [String]
46
+ def to_sparql(**options)
47
+ "ABS(#{operands.first.to_sparql(**options)})"
48
+ end
29
49
  end # Abs
30
50
  end # Operator
31
51
  end; end # SPARQL::Algebra
@@ -6,8 +6,15 @@ module SPARQL; module Algebra
6
6
  #
7
7
  # The ADD operation is a shortcut for inserting all data from an input graph into a destination graph. Data from the input graph is not affected, and initial data from the destination graph, if any, is kept intact.
8
8
  #
9
- # @example
10
- # (add default <a>)
9
+ # [35] Add ::= "ADD" "SILENT"? GraphOrDefault "TO" GraphOrDefault
10
+ #
11
+ # @example SPARQL Update
12
+ # PREFIX : <http://example.org/>
13
+ # ADD DEFAULT TO :g1
14
+ #
15
+ # @example SSE
16
+ # (prefix ((: <http://example.org/>))
17
+ # (update (add default :g1)))
11
18
  #
12
19
  # @see https://www.w3.org/TR/sparql11-update/#add
13
20
  class Add < Operator
@@ -51,6 +58,18 @@ module SPARQL; module Algebra
51
58
  end
52
59
  queryable
53
60
  end
61
+
62
+ ##
63
+ #
64
+ # Returns a partial SPARQL grammar for this operator.
65
+ #
66
+ # @return [String]
67
+ def to_sparql(**options)
68
+ *args, last = operands.dup
69
+ args += [:TO, last]
70
+
71
+ "ADD " + args.to_sparql(**options)
72
+ end
54
73
  end # Add
55
74
  end # Operator
56
75
  end; end # SPARQL::Algebra
@@ -7,8 +7,23 @@ module SPARQL; module Algebra
7
7
  #
8
8
  # eval(Path(X, alt(P,Q), Y)) = Union(eval(Path(X, P, Y)), eval(Path(X, Q, Y)))
9
9
  #
10
- # @example
11
- # (alt a b)
10
+ # [89] PathAlternative ::= PathSequence ( '|' PathSequence )*
11
+ #
12
+ # @example SPARQL Query
13
+ # PREFIX : <http://www.example.org/>
14
+ # SELECT ?t
15
+ # WHERE {
16
+ # :a :p1|:p2/:p3|:p4 ?t
17
+ # }
18
+ #
19
+ # @example SSE
20
+ # (prefix ((: <http://www.example.org/>))
21
+ # (project (?t)
22
+ # (path :a
23
+ # (alt
24
+ # (alt :p1 (seq :p2 :p3))
25
+ # :p4)
26
+ # ?t)))
12
27
  #
13
28
  # @see https://www.w3.org/TR/sparql11-query/#defn_evalPP_alternative
14
29
  class Alt < Operator::Binary
@@ -57,6 +72,15 @@ module SPARQL; module Algebra
57
72
  query = Union.new(qa, qb)
58
73
  queryable.query(query, depth: options[:depth].to_i + 1, **options, &block)
59
74
  end
75
+
76
+ ##
77
+ #
78
+ # Returns a partial SPARQL grammar for this operator.
79
+ #
80
+ # @return [String]
81
+ def to_sparql(**options)
82
+ "#{operands.first.to_sparql(**options)}|#{operands.last.to_sparql(**options)}"
83
+ end
60
84
  end # Alt
61
85
  end # Operator
62
86
  end; end # SPARQL::Algebra
@@ -3,9 +3,22 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL logical `and` operator.
5
5
  #
6
- # @example
7
- # (&& ?x ?y)
8
- # (and ?x ?y)
6
+ # [112] ConditionalAndExpression::= ValueLogical ( '&&' ValueLogical )*
7
+ #
8
+ # @example SPARQL Grammar
9
+ # PREFIX xsd: <http://www.w3.org/2001/XMLSchema#>
10
+ # PREFIX : <http://example.org/ns#>
11
+ # SELECT ?a
12
+ # WHERE { ?a :p ?v .
13
+ # FILTER ("true"^^xsd:boolean && ?v) .
14
+ # }
15
+ #
16
+ # @example SSE
17
+ # (prefix
18
+ # ((xsd: <http://www.w3.org/2001/XMLSchema#>) (: <http://example.org/ns#>))
19
+ # (project (?a)
20
+ # (filter (&& true ?v)
21
+ # (bgp (triple ?a :p ?v)))))
9
22
  #
10
23
  # @see https://www.w3.org/TR/sparql11-query/#func-logical-and
11
24
  # @see https://www.w3.org/TR/sparql11-query/#evaluation
@@ -60,6 +73,15 @@ module SPARQL; module Algebra
60
73
  else RDF::Literal(left && right)
61
74
  end
62
75
  end
76
+
77
+ ##
78
+ #
79
+ # Returns a partial SPARQL grammar for this operator.
80
+ #
81
+ # @return [String]
82
+ def to_sparql(**options)
83
+ "(#{operands.first.to_sparql(**options)} && #{operands.last.to_sparql(**options)})"
84
+ end
63
85
  end # And
64
86
  end # Operator
65
87
  end; end # SPARQL::Algebra
@@ -3,7 +3,15 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL ascending sort operator.
5
5
  #
6
- # @example
6
+ # [24] OrderCondition ::= ( ( 'ASC' | 'DESC' ) BrackettedExpression ) | ( Constraint | Var )
7
+ #
8
+ # @example SPARQL Query
9
+ # PREFIX foaf: <http://xmlns.com/foaf/0.1/>
10
+ # SELECT ?name
11
+ # WHERE { ?x foaf:name ?name }
12
+ # ORDER BY ASC(?name)
13
+ #
14
+ # @example SSE
7
15
  # (prefix ((foaf: <http://xmlns.com/foaf/0.1/>))
8
16
  # (project (?name)
9
17
  # (order ((asc ?name))
@@ -27,6 +35,17 @@ module SPARQL; module Algebra
27
35
  def evaluate(bindings, **options)
28
36
  operand(0).evaluate(bindings, depth: options[:depth].to_i + 1, **options)
29
37
  end
38
+
39
+ ##
40
+ #
41
+ # Returns a partial SPARQL grammar for this operator.
42
+ #
43
+ # Provides order to descendant query.
44
+ #
45
+ # @return [String]
46
+ def to_sparql(**options)
47
+ "ASC(#{operands.last.to_sparql(**options)})"
48
+ end
30
49
  end # Asc
31
50
  end # Operator
32
51
  end; end # SPARQL::Algebra
@@ -5,7 +5,13 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Applications can use the ASK form to test whether or not a query pattern has a solution. No information is returned about the possible query solutions, just whether or not a solution exists.
7
7
  #
8
- # @example
8
+ # [12] AskQuery ::= 'ASK' DatasetClause* WhereClause ValuesClause
9
+ #
10
+ # @example SPARQL Query
11
+ # PREFIX : <http://example/>
12
+ # ASK { :x :p ?x }
13
+ #
14
+ # @example SSE
9
15
  # (prefix ((: <http://example/>))
10
16
  # (ask
11
17
  # (bgp (triple :x :p ?x))))
@@ -41,6 +47,16 @@ module SPARQL; module Algebra
41
47
  def query_yields_boolean?
42
48
  true
43
49
  end
50
+
51
+ ##
52
+ #
53
+ # Returns a partial SPARQL grammar for this term.
54
+ #
55
+ # @return [String]
56
+ def to_sparql(**options)
57
+ "ASK\n" +
58
+ operands.first.to_sparql(top_level: true, project: nil, **options)
59
+ end
44
60
  end # Ask
45
61
  end # Operator
46
62
  end; end # SPARQL::Algebra
@@ -3,7 +3,14 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL `avg` set function.
5
5
  #
6
- # @example
6
+ # [127] Aggregate::= ... | 'AVG' '(' 'DISTINCT'? Expression ')'
7
+ #
8
+ # @example SPARQL Query
9
+ # PREFIX : <http://www.example.org/>
10
+ # SELECT (AVG(?o) AS ?avg)
11
+ # WHERE { ?s :dec ?o }
12
+ #
13
+ # @example SSE
7
14
  # (prefix ((: <http://www.example.org/>))
8
15
  # (project (?avg)
9
16
  # (extend ((?avg ??.0))
@@ -40,6 +47,15 @@ module SPARQL; module Algebra
40
47
  raise TypeError, "Averaging non-numeric types: #{enum.flatten}"
41
48
  end
42
49
  end
50
+
51
+ ##
52
+ #
53
+ # Returns a partial SPARQL grammar for this operator.
54
+ #
55
+ # @return [String]
56
+ def to_sparql(**options)
57
+ "AVG(#{operands.to_sparql(**options)})"
58
+ end
43
59
  end # Avg
44
60
  end # Operator
45
61
  end; end # SPARQL::Algebra
@@ -3,7 +3,13 @@ module SPARQL; module Algebra
3
3
  ##
4
4
  # The SPARQL GraphPattern `base` operator.
5
5
  #
6
- # @example
6
+ # [5] BaseDecl ::= 'BASE' IRIREF
7
+ #
8
+ # @example SPARQL Grammar
9
+ # BASE <http://example.org/>
10
+ # SELECT * { <a> <b> 123.0 }
11
+ #
12
+ # @example SSE
7
13
  # (base <http://example.org/>
8
14
  # (bgp (triple <a> <b> 123.0)))
9
15
  #
@@ -56,6 +62,17 @@ module SPARQL; module Algebra
56
62
  def query_yields_statements?
57
63
  operands.last.query_yields_statements?
58
64
  end
65
+
66
+ ##
67
+ #
68
+ # Returns a partial SPARQL grammar for this term.
69
+ #
70
+ # @return [String]
71
+ def to_sparql(**options)
72
+ str = "BASE #{operands.first.to_sparql}\n"
73
+
74
+ str << operands.last.to_sparql(base_uri: operands.first, **options)
75
+ end
59
76
  end # Base
60
77
  end # Operator
61
78
  end; end # SPARQL::Algebra
@@ -5,7 +5,11 @@ module SPARQL; module Algebra
5
5
  #
6
6
  # Query with `graph_name` set to false.
7
7
  #
8
- # @example
8
+ # @example SPARQL Grammar
9
+ # PREFIX : <http://example/>
10
+ # SELECT * { :s :p :o }
11
+ #
12
+ # @example SSE
9
13
  # (prefix ((: <http://example/>))
10
14
  # (bgp (triple ?s ?p ?o)))
11
15
  #