sparql 1.1.5 → 1.1.6
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 +36 -32
- data/VERSION +1 -1
- data/bin/sparql +8 -6
- data/lib/sparql.rb +4 -2
- data/lib/sparql/algebra.rb +74 -4
- data/lib/sparql/algebra/aggregate.rb +1 -1
- data/lib/sparql/algebra/evaluatable.rb +1 -1
- data/lib/sparql/algebra/expression.rb +24 -16
- data/lib/sparql/algebra/extensions.rb +37 -9
- data/lib/sparql/algebra/operator.rb +75 -12
- data/lib/sparql/algebra/operator/add.rb +41 -19
- data/lib/sparql/algebra/operator/and.rb +2 -2
- data/lib/sparql/algebra/operator/asc.rb +1 -1
- data/lib/sparql/algebra/operator/ask.rb +1 -1
- data/lib/sparql/algebra/operator/base.rb +1 -1
- data/lib/sparql/algebra/operator/bgp.rb +1 -1
- data/lib/sparql/algebra/operator/bnode.rb +1 -1
- data/lib/sparql/algebra/operator/clear.rb +63 -0
- data/lib/sparql/algebra/operator/coalesce.rb +1 -1
- data/lib/sparql/algebra/operator/concat.rb +3 -3
- data/lib/sparql/algebra/operator/construct.rb +2 -2
- data/lib/sparql/algebra/operator/copy.rb +64 -0
- data/lib/sparql/algebra/operator/create.rb +49 -0
- data/lib/sparql/algebra/operator/dataset.rb +6 -31
- data/lib/sparql/algebra/operator/delete.rb +55 -0
- data/lib/sparql/algebra/operator/delete_data.rb +41 -0
- data/lib/sparql/algebra/operator/delete_where.rb +57 -0
- data/lib/sparql/algebra/operator/distinct.rb +1 -1
- data/lib/sparql/algebra/operator/drop.rb +66 -0
- data/lib/sparql/algebra/operator/exists.rb +2 -2
- data/lib/sparql/algebra/operator/exprlist.rb +1 -1
- data/lib/sparql/algebra/operator/extend.rb +3 -3
- data/lib/sparql/algebra/operator/filter.rb +2 -2
- data/lib/sparql/algebra/operator/graph.rb +39 -5
- data/lib/sparql/algebra/operator/group.rb +5 -5
- data/lib/sparql/algebra/operator/group_concat.rb +1 -1
- data/lib/sparql/algebra/operator/if.rb +3 -3
- data/lib/sparql/algebra/operator/in.rb +1 -1
- data/lib/sparql/algebra/operator/insert.rb +54 -0
- data/lib/sparql/algebra/operator/insert_data.rb +41 -0
- data/lib/sparql/algebra/operator/join.rb +2 -2
- data/lib/sparql/algebra/operator/lcase.rb +1 -1
- data/lib/sparql/algebra/operator/left_join.rb +2 -2
- data/lib/sparql/algebra/operator/load.rb +48 -0
- data/lib/sparql/algebra/operator/minus.rb +2 -2
- data/lib/sparql/algebra/operator/modify.rb +53 -0
- data/lib/sparql/algebra/operator/move.rb +67 -0
- data/lib/sparql/algebra/operator/notexists.rb +1 -1
- data/lib/sparql/algebra/operator/notin.rb +2 -2
- data/lib/sparql/algebra/operator/or.rb +2 -2
- data/lib/sparql/algebra/operator/order.rb +3 -3
- data/lib/sparql/algebra/operator/plus.rb +14 -8
- data/lib/sparql/algebra/operator/prefix.rb +1 -1
- data/lib/sparql/algebra/operator/project.rb +1 -1
- data/lib/sparql/algebra/operator/reduced.rb +1 -1
- data/lib/sparql/algebra/operator/replace.rb +1 -1
- data/lib/sparql/algebra/operator/slice.rb +1 -1
- data/lib/sparql/algebra/operator/strafter.rb +1 -1
- data/lib/sparql/algebra/operator/strbefore.rb +2 -2
- data/lib/sparql/algebra/operator/strdt.rb +1 -1
- data/lib/sparql/algebra/operator/strlang.rb +1 -1
- data/lib/sparql/algebra/operator/substr.rb +2 -2
- data/lib/sparql/algebra/operator/ucase.rb +1 -1
- data/lib/sparql/algebra/operator/union.rb +1 -1
- data/lib/sparql/algebra/operator/update.rb +44 -0
- data/lib/sparql/algebra/operator/using.rb +40 -0
- data/lib/sparql/algebra/operator/with.rb +72 -0
- data/lib/sparql/algebra/update.rb +56 -0
- data/lib/sparql/extensions.rb +8 -8
- data/lib/sparql/grammar.rb +31 -8
- data/lib/sparql/grammar/meta.rb +3758 -3273
- data/lib/sparql/grammar/parser11.rb +240 -46
- data/lib/sparql/grammar/terminals11.rb +5 -5
- data/lib/sparql/results.rb +26 -26
- metadata +38 -30
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7a1d4a5797ead6402462b84ed480cca4a748f2cb
|
4
|
+
data.tar.gz: 86cae5d9912179a3e8c08ac5d0b92ac3949787fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 69ef15c1ef1a15a051fb7f9837d2a4bb584c4d557ce4d52958cd214752eae33c80d0e87e5cdbf98527b4c8bb73041969ec3f2b2d2790386459a08b7c3a7baa60
|
7
|
+
data.tar.gz: 088b6db9ad1d2e7c1019956bd112be2abafbf1fcf4004c4a410ac5eb6a402a0c36e7a80b4f8d73b66ac0fa584683b9406494a1ba7552139a7dfd1d245d39b155
|
data/README.md
CHANGED
@@ -17,29 +17,26 @@ This is a [Ruby][] implementation of [SPARQL][] for [RDF.rb][].
|
|
17
17
|
* SPARQL CONSTRUCT or DESCRIBE serialized based on Format, Extension of Mime Type
|
18
18
|
using available RDF Writers (see [Linked Data][])
|
19
19
|
* SPARQL Client for accessing remote SPARQL endpoints.
|
20
|
+
* SPARQL Update
|
20
21
|
* [Rack][] and [Sinatra][] middleware to perform [HTTP content negotiation][conneg] for result formats
|
21
22
|
* Compatible with any [Rack][] or [Sinatra][] application and any Rack-based framework.
|
22
23
|
* Helper method for describing [SPARQL Service Description][SSD]
|
23
|
-
* Compatible with Ruby >= 1.9.
|
24
|
+
* Compatible with Ruby >= 1.9.3.
|
24
25
|
* Compatible with older Ruby versions with the help of the [Backports][] gem.
|
25
26
|
* Supports Unicode query strings both on all versions of Ruby.
|
26
27
|
|
27
28
|
## Description
|
28
29
|
|
29
|
-
The {SPARQL} gem implements [SPARQL 1.1 Query][], and provides [Rack][] and [Sinatra][]
|
30
|
-
middleware to provide results using [HTTP Content Negotiation][conneg].
|
30
|
+
The {SPARQL} gem implements [SPARQL 1.1 Query][], and [SPARQL 1.1 Update][], and provides [Rack][] and [Sinatra][] middleware to provide results using [HTTP Content Negotiation][conneg].
|
31
31
|
|
32
|
-
* {SPARQL::Grammar} implements a [SPARQL 1.1 Query][] parser generating [SPARQL S-Expressions (SSE)][SSE].
|
32
|
+
* {SPARQL::Grammar} implements a [SPARQL 1.1 Query][] and [SPARQL 1.1 Update][] parser generating [SPARQL S-Expressions (SSE)][SSE].
|
33
33
|
* Support for [Property Paths][] is excluded.
|
34
34
|
See the section on [SPARQL 1.1 Query][] extensions and limitations for further detail.
|
35
|
-
* {SPARQL::Algebra} executes SSE against Any `RDF::Graph` or `RDF::Repository`, including
|
36
|
-
|
37
|
-
* {Rack::SPARQL} and {Sinatra::SPARQL} provide middleware components to format results
|
38
|
-
using an appropriate format based on [HTTP content negotiation][conneg].
|
35
|
+
* {SPARQL::Algebra} executes SSE against Any `RDF::Graph` or `RDF::Repository`, including compliant [RDF.rb][] repository adaptors such as [RDF::DO][] and [RDF::Mongo][].
|
36
|
+
* {Rack::SPARQL} and {Sinatra::SPARQL} provide middleware components to format results using an appropriate format based on [HTTP content negotiation][conneg].
|
39
37
|
|
40
38
|
### [SPARQL 1.1 Query][] Extensions and Limitations
|
41
|
-
The {SPARQL} gem uses the [SPARQL 1.1 Query][] {file:etc/sparql11.
|
42
|
-
much more capability than [SPARQL 1.0][], but has a few limitations:
|
39
|
+
The {SPARQL} gem uses the [SPARQL 1.1 Query][] {file:etc/sparql11.html EBNF grammar}, which provides much more capability than [SPARQL 1.0][], but has a few limitations:
|
43
40
|
|
44
41
|
* The format for decimal datatypes has changed in [RDF 1.1][]; they may no
|
45
42
|
longer have a trailing ".", although they do not need a leading digit.
|
@@ -57,11 +54,13 @@ The SPARQL gem now implements the following [SPARQL 1.1 Query][] operations:
|
|
57
54
|
* [Exists](http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#func-filter-exists)
|
58
55
|
* [Negation](http://www.w3.org/TR/2013/REC-sparql11-query-20130321/#negation)
|
59
56
|
|
57
|
+
The gem also includes the following [SPARQL 1.1 Update][] operations:
|
58
|
+
* [Graph Update](http://www.w3.org/TR/sparql11-update/#graphUpdate)
|
59
|
+
* [Graph Management](http://www.w3.org/TR/sparql11-update/#graphManagement)
|
60
|
+
|
60
61
|
The only major area of [SPARQL 1.1 Query][] missing is
|
61
|
-
[Property Paths][], which
|
62
|
-
will be in later release along with:
|
62
|
+
[Property Paths][], which will be in later release along with:
|
63
63
|
|
64
|
-
* [Update][SPARQL 1.1 Update],
|
65
64
|
* [Federated Query][SPARQL 1.1 Federated Query],
|
66
65
|
* [Entailment Regimes][SPARQL 1.1 Entailment Regimes],
|
67
66
|
* [Protocol][SPARQL 1.1 Protocol], and
|
@@ -117,11 +116,7 @@ for N-Triples, N-Quads, Turtle, RDF/XML, RDF/JSON, JSON-LD, RDFa, TriG and TriX.
|
|
117
116
|
|
118
117
|
### Remote datasets
|
119
118
|
|
120
|
-
A SPARQL query containing `FROM` or `FROM NAMED` will load the referenced IRI unless the repository
|
121
|
-
already contains a context with that same IRI. This is performed using [RDF.rb][] `RDF::Util::File.open_file`
|
122
|
-
passing HTTP Accept headers for various available RDF formats. For best results, require [Linked Data][] to enable
|
123
|
-
a full set of RDF formats in the `GET` request. Also, consider overriding `RDF::Util::File.open_file` with
|
124
|
-
an implementation with support for HTTP Get headers (such as `Net::HTTP`).
|
119
|
+
A SPARQL query containing `FROM` or `FROM NAMED` (also `UPDATE` or `UPDATE NAMED`) will load the referenced IRI unless the repository already contains a context with that same IRI. This is performed using [RDF.rb][] `RDF::Util::File.open_file` passing HTTP Accept headers for various available RDF formats. For best results, require [Linked Data][] to enable a full set of RDF formats in the `GET` request. Also, consider overriding `RDF::Util::File.open_file` with an implementation with support for HTTP Get headers (such as `Net::HTTP`).
|
125
120
|
|
126
121
|
Queries using datasets are re-written to use the identified graphs for `FROM` and `FROM NAMED` by filtering the results, allowing the use of a repository that contains many graphs without confusing information.
|
127
122
|
|
@@ -154,6 +149,15 @@ a full set of RDF formats.
|
|
154
149
|
result.inspect
|
155
150
|
end
|
156
151
|
|
152
|
+
### Updating a respository
|
153
|
+
|
154
|
+
queryable = RDF::Repository.load("etc/doap.ttl")
|
155
|
+
sse = SPARQL.parse(%(
|
156
|
+
PREFIX doap: <http://usefulinc.com/ns/doap#>
|
157
|
+
INSERT DATA { <http://rubygems.org/gems/sparql> doap:implements <http://www.w3.org/TR/sparql11-update/>}
|
158
|
+
), update: true)
|
159
|
+
sse.execute(queryable)
|
160
|
+
|
157
161
|
### Rendering solutions as JSON, XML, CSV, TSV or HTML
|
158
162
|
queryable = RDF::Repository.load("etc/doap.ttl")
|
159
163
|
solutions = SPARQL.execute("SELECT * WHERE { ?s ?p ?o }", queryable)
|
@@ -212,7 +216,7 @@ a full set of RDF formats.
|
|
212
216
|
require 'uri'
|
213
217
|
|
214
218
|
get '/' do
|
215
|
-
settings.sparql_options.replace(:
|
219
|
+
settings.sparql_options.replace(standard_prefixes: true)
|
216
220
|
repository = RDF::Repository.new do |graph|
|
217
221
|
graph << [RDF::Node.new, RDF::DC.title, "Hello, world!"]
|
218
222
|
end
|
@@ -220,11 +224,11 @@ a full set of RDF formats.
|
|
220
224
|
query = params["query"].to_s.match(/^http:/) ? RDF::Util::File.open_file(params["query"]) : ::URI.decode(params["query"].to_s)
|
221
225
|
SPARQL.execute(query, repository)
|
222
226
|
else
|
223
|
-
settings.sparql_options.merge!(:
|
224
|
-
:
|
225
|
-
:
|
227
|
+
settings.sparql_options.merge!(prefixes: {
|
228
|
+
ssd: "http://www.w3.org/ns/sparql-service-description#",
|
229
|
+
void: "http://rdfs.org/ns/void#"
|
226
230
|
})
|
227
|
-
service_description(:
|
231
|
+
service_description(repo: repository)
|
228
232
|
end
|
229
233
|
end
|
230
234
|
|
@@ -249,19 +253,19 @@ Full documentation available on [Rubydoc.info][SPARQL doc]
|
|
249
253
|
|
250
254
|
## Dependencies
|
251
255
|
|
252
|
-
* [Ruby](http://ruby-lang.org/) (>= 1.9.
|
253
|
-
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 1.
|
254
|
-
* [SPARQL::Client](https://rubygems.org/gems/sparql-client) (>= 1.
|
255
|
-
* [SXP](https://rubygems.org/gems/sxp) (>= 0.1.
|
256
|
+
* [Ruby](http://ruby-lang.org/) (>= 1.9.3)
|
257
|
+
* [RDF.rb](http://rubygems.org/gems/rdf) (>= 1.1.12)
|
258
|
+
* [SPARQL::Client](https://rubygems.org/gems/sparql-client) (>= 1.1.3)
|
259
|
+
* [SXP](https://rubygems.org/gems/sxp) (>= 0.1.3)
|
256
260
|
* [Builder](https://rubygems.org/gems/builder) (>= 3.0.0)
|
257
|
-
* [JSON](https://rubygems.org/gems/json) (>= 1.
|
258
|
-
* Soft dependency on [Linked Data][] (>= 1.
|
259
|
-
* Soft dependency on [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.
|
261
|
+
* [JSON](https://rubygems.org/gems/json) (>= 1.8.2)
|
262
|
+
* Soft dependency on [Linked Data][] (>= 1.1)
|
263
|
+
* Soft dependency on [Nokogiri](http://rubygems.org/gems/nokogiri) (>= 1.6.6)
|
260
264
|
Falls back to REXML for XML parsing Builder for XML serializing. Nokogiri is much more efficient
|
261
265
|
* Soft dependency on [Equivalent XML](https://rubygems.org/gems/equivalent-xml) (>= 0.3.0)
|
262
266
|
Equivalent XML performs more efficient comparisons of XML Literals when Nokogiri is included
|
263
|
-
* Soft dependency on [Rack][] (>= 1.
|
264
|
-
* Soft dependency on [Sinatra][] (>= 1.
|
267
|
+
* Soft dependency on [Rack][] (>= 1.6.0)
|
268
|
+
* Soft dependency on [Sinatra][] (>= 1.4.6)
|
265
269
|
|
266
270
|
## Installation
|
267
271
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.1.
|
1
|
+
1.1.6
|
data/bin/sparql
CHANGED
@@ -11,7 +11,7 @@ require 'getoptlong'
|
|
11
11
|
|
12
12
|
def run(input, options = {})
|
13
13
|
if options[:debug]
|
14
|
-
puts "input graph:\n#{options[:graph].dump(:ttl, :
|
14
|
+
puts "input graph:\n#{options[:graph].dump(:ttl, standard_prefixes: true)}\n" if options[:graph]
|
15
15
|
puts "query:\n#{input}\n"
|
16
16
|
end
|
17
17
|
options[:graph] ||= RDF::Repository.new
|
@@ -21,7 +21,7 @@ def run(input, options = {})
|
|
21
21
|
end
|
22
22
|
|
23
23
|
query = if options[:sse]
|
24
|
-
SPARQL::Algebra.parse(input, {:debug
|
24
|
+
SPARQL::Algebra.parse(input, {debug: options[:debug], update: options[:update]})
|
25
25
|
else
|
26
26
|
# Only do grammar debugging if we're generating SSE
|
27
27
|
SPARQL::Grammar.parse(input, options)
|
@@ -30,10 +30,10 @@ def run(input, options = {})
|
|
30
30
|
puts ("\nSSE:\n" + query.to_sse) if options[:debug] || options[:to_sse]
|
31
31
|
|
32
32
|
unless options[:to_sse]
|
33
|
-
res = query.execute(options[:graph], :
|
33
|
+
res = query.execute(options[:graph], debug: options[:debug])
|
34
34
|
puts res.inspect if options[:verbose]
|
35
35
|
puts case res
|
36
|
-
when RDF::Graph then res.dump(:ttl, :
|
36
|
+
when RDF::Graph then res.dump(:ttl, base_uri: query.base_uri, prefixes: query.prefixes, standard_prefixes: true)
|
37
37
|
when RDF::Literal then res.inspect
|
38
38
|
else res.map {|s| s.bindings.map {|k,v| "#{k}: #{v}"}}.join("\n")
|
39
39
|
end
|
@@ -52,7 +52,7 @@ opts = GetoptLong.new(
|
|
52
52
|
)
|
53
53
|
|
54
54
|
options = {
|
55
|
-
:
|
55
|
+
graph: RDF::Repository.new,
|
56
56
|
}
|
57
57
|
|
58
58
|
input = nil
|
@@ -65,6 +65,7 @@ opts.each do |opt, arg|
|
|
65
65
|
when '--sse' then options[:sse] = true
|
66
66
|
when '--to-sse' then options[:to_sse] = true
|
67
67
|
when '--debug' then options[:debug] = true
|
68
|
+
when '--update' then options[:update] = true
|
68
69
|
when '--verbose' then options[:verbose] = true
|
69
70
|
when "--help"
|
70
71
|
puts "Usage: #{$0} [options] file-or-uri ..."
|
@@ -76,6 +77,7 @@ opts.each do |opt, arg|
|
|
76
77
|
puts " --sse: Input is in SSE format"
|
77
78
|
puts " --to-sse: Generate SSE instead of running query"
|
78
79
|
puts " --debug: Display detailed debug output"
|
80
|
+
puts " --update: Process query as a SPARQL Update"
|
79
81
|
puts " --verbose: Display details of processing"
|
80
82
|
puts " --help,-?: This message"
|
81
83
|
exit(0)
|
@@ -88,7 +90,7 @@ if ARGV.empty?
|
|
88
90
|
else
|
89
91
|
ARGV.each do |test_file|
|
90
92
|
puts "parse #{test_file}"
|
91
|
-
run(RDF::Util::File.open_file(test_file).read, options.merge(:
|
93
|
+
run(RDF::Util::File.open_file(test_file).read, options.merge(base_uri: RDF::URI(test_file)))
|
92
94
|
end
|
93
95
|
end
|
94
96
|
puts
|
data/lib/sparql.rb
CHANGED
@@ -21,13 +21,15 @@ module SPARQL
|
|
21
21
|
#
|
22
22
|
# @param [IO, StringIO, String, #to_s] query
|
23
23
|
# @param [Hash{Symbol => Object}] options
|
24
|
+
# @option options [Boolean] :update (false)
|
25
|
+
# Parse starting with UpdateUnit production, QueryUnit otherwise.
|
24
26
|
# @return [SPARQL::Query]
|
25
27
|
# The resulting query may be executed against
|
26
28
|
# a `queryable` object such as an RDF::Graph
|
27
29
|
# or RDF::Repository.
|
28
30
|
# @raise [Parser::Error] on invalid input
|
29
31
|
def self.parse(query, options = {})
|
30
|
-
query = Grammar::Parser.new(query, options).parse
|
32
|
+
query = Grammar::Parser.new(query, options).parse(options[:update] ? :UpdateUnit : :QueryUnit)
|
31
33
|
end
|
32
34
|
|
33
35
|
##
|
@@ -82,7 +84,7 @@ module SPARQL
|
|
82
84
|
queryable.load(uri)
|
83
85
|
end
|
84
86
|
[options[:named_graph_uri]].flatten.each do |uri|
|
85
|
-
queryable.load(uri, :
|
87
|
+
queryable.load(uri, context: uri)
|
86
88
|
end
|
87
89
|
end
|
88
90
|
query.execute(queryable, &block)
|
data/lib/sparql/algebra.rb
CHANGED
@@ -176,7 +176,7 @@ module SPARQL
|
|
176
176
|
# solutions = RDF::Query.execute(RDF::Graph.load('etc/doap.ttl')) do |query|
|
177
177
|
# query.pattern [:person, RDF.type, RDF::FOAF.Person]
|
178
178
|
# query.pattern [:person, RDF::FOAF.name, :name]
|
179
|
-
# query.pattern [:person, RDF::FOAF.mbox, :email], :
|
179
|
+
# query.pattern [:person, RDF::FOAF.mbox, :email], optional: true
|
180
180
|
# end
|
181
181
|
#
|
182
182
|
# # Find people who have a name but don't have a known e-mail address:
|
@@ -209,8 +209,8 @@ module SPARQL
|
|
209
209
|
# Expressions can optionally be [memoized][memoization], which can speed up
|
210
210
|
# repeatedly executing the expression on a solution sequence:
|
211
211
|
#
|
212
|
-
# SPARQL::Algebra::Expression.parse(sse, :
|
213
|
-
# Operator.new(*operands, :
|
212
|
+
# SPARQL::Algebra::Expression.parse(sse, memoize: true)
|
213
|
+
# Operator.new(*operands, memoize: true)
|
214
214
|
#
|
215
215
|
# Memoization is implemented using RDF.rb's [RDF::Util::Cache][] utility
|
216
216
|
# library, a weak-reference cache that allows values contained in the cache to
|
@@ -225,58 +225,127 @@ module SPARQL
|
|
225
225
|
# ## Documentation
|
226
226
|
#
|
227
227
|
# * {SPARQL::Algebra}
|
228
|
+
# * {SPARQL::Algebra::Aggregate}
|
229
|
+
# * {SPARQL::Algebra::Evaluatable}
|
228
230
|
# * {SPARQL::Algebra::Expression}
|
229
231
|
# * {SPARQL::Algebra::Query}
|
232
|
+
# * {SPARQL::Algebra::Update}
|
230
233
|
# * {SPARQL::Algebra::Operator}
|
234
|
+
# * {SPARQL::Algebra::Operator::Abs}
|
231
235
|
# * {SPARQL::Algebra::Operator::Add}
|
232
236
|
# * {SPARQL::Algebra::Operator::And}
|
233
237
|
# * {SPARQL::Algebra::Operator::Asc}
|
234
238
|
# * {SPARQL::Algebra::Operator::Ask}
|
239
|
+
# * {SPARQL::Algebra::Operator::Avg}
|
235
240
|
# * {SPARQL::Algebra::Operator::Base}
|
241
|
+
# * {SPARQL::Algebra::Operator::BGP}
|
236
242
|
# * {SPARQL::Algebra::Operator::Bound}
|
243
|
+
# * {SPARQL::Algebra::Operator::Ceil}
|
244
|
+
# * {SPARQL::Algebra::Operator::Clear}
|
245
|
+
# * {SPARQL::Algebra::Operator::Coalesce}
|
237
246
|
# * {SPARQL::Algebra::Operator::Compare}
|
247
|
+
# * {SPARQL::Algebra::Operator::Concat}
|
238
248
|
# * {SPARQL::Algebra::Operator::Construct}
|
249
|
+
# * {SPARQL::Algebra::Operator::Contains}
|
250
|
+
# * {SPARQL::Algebra::Operator::Copy}
|
251
|
+
# * {SPARQL::Algebra::Operator::Count}
|
252
|
+
# * {SPARQL::Algebra::Operator::Create}
|
239
253
|
# * {SPARQL::Algebra::Operator::Dataset}
|
240
254
|
# * {SPARQL::Algebra::Operator::Datatype}
|
255
|
+
# * {SPARQL::Algebra::Operator::Day}
|
256
|
+
# * {SPARQL::Algebra::Operator::Delete}
|
257
|
+
# * {SPARQL::Algebra::Operator::DeleteData}
|
258
|
+
# * {SPARQL::Algebra::Operator::DeleteWhere}
|
241
259
|
# * {SPARQL::Algebra::Operator::Desc}
|
242
260
|
# * {SPARQL::Algebra::Operator::Describe}
|
243
261
|
# * {SPARQL::Algebra::Operator::Distinct}
|
244
262
|
# * {SPARQL::Algebra::Operator::Divide}
|
263
|
+
# * {SPARQL::Algebra::Operator::Drop}
|
264
|
+
# * {SPARQL::Algebra::Operator::EncodeForURI}
|
245
265
|
# * {SPARQL::Algebra::Operator::Equal}
|
246
266
|
# * {SPARQL::Algebra::Operator::Exprlist}
|
267
|
+
# * {SPARQL::Algebra::Operator::Extend}
|
247
268
|
# * {SPARQL::Algebra::Operator::Filter}
|
269
|
+
# * {SPARQL::Algebra::Operator::Floor}
|
248
270
|
# * {SPARQL::Algebra::Operator::Graph}
|
249
271
|
# * {SPARQL::Algebra::Operator::GreaterThan}
|
250
272
|
# * {SPARQL::Algebra::Operator::GreaterThanOrEqual}
|
273
|
+
# * {SPARQL::Algebra::Operator::Group}
|
274
|
+
# * {SPARQL::Algebra::Operator::GroupConcat}
|
275
|
+
# * {SPARQL::Algebra::Operator::Hours}
|
276
|
+
# * {SPARQL::Algebra::Operator::If}
|
277
|
+
# * {SPARQL::Algebra::Operator::In}
|
278
|
+
# * {SPARQL::Algebra::Operator::Insert}
|
279
|
+
# * {SPARQL::Algebra::Operator::InsertData}
|
280
|
+
# * {SPARQL::Algebra::Operator::IRI}
|
251
281
|
# * {SPARQL::Algebra::Operator::IsBlank}
|
252
282
|
# * {SPARQL::Algebra::Operator::IsIRI}
|
253
283
|
# * {SPARQL::Algebra::Operator::IsLiteral}
|
284
|
+
# * {SPARQL::Algebra::Operator::IsNumeric}
|
254
285
|
# * {SPARQL::Algebra::Operator::Join}
|
255
286
|
# * {SPARQL::Algebra::Operator::Lang}
|
256
287
|
# * {SPARQL::Algebra::Operator::LangMatches}
|
257
288
|
# * {SPARQL::Algebra::Operator::LeftJoin}
|
258
289
|
# * {SPARQL::Algebra::Operator::LessThan}
|
259
290
|
# * {SPARQL::Algebra::Operator::LessThanOrEqual}
|
291
|
+
# * {SPARQL::Algebra::Operator::Max}
|
292
|
+
# * {SPARQL::Algebra::Operator::MD5}
|
293
|
+
# * {SPARQL::Algebra::Operator::Min}
|
260
294
|
# * {SPARQL::Algebra::Operator::Minus}
|
295
|
+
# * {SPARQL::Algebra::Operator::Minutes}
|
296
|
+
# * {SPARQL::Algebra::Operator::Modify}
|
297
|
+
# * {SPARQL::Algebra::Operator::Month}
|
298
|
+
# * {SPARQL::Algebra::Operator::Move}
|
261
299
|
# * {SPARQL::Algebra::Operator::Multiply}
|
300
|
+
# * {SPARQL::Algebra::Operator::Negate}
|
262
301
|
# * {SPARQL::Algebra::Operator::Not}
|
263
302
|
# * {SPARQL::Algebra::Operator::NotEqual}
|
303
|
+
# * {SPARQL::Algebra::Operator::NotExists}
|
304
|
+
# * {SPARQL::Algebra::Operator::NotIn}
|
305
|
+
# * {SPARQL::Algebra::Operator::Now}
|
264
306
|
# * {SPARQL::Algebra::Operator::Or}
|
265
307
|
# * {SPARQL::Algebra::Operator::Order}
|
266
308
|
# * {SPARQL::Algebra::Operator::Plus}
|
267
309
|
# * {SPARQL::Algebra::Operator::Prefix}
|
268
310
|
# * {SPARQL::Algebra::Operator::Project}
|
311
|
+
# * {SPARQL::Algebra::Operator::Rand}
|
269
312
|
# * {SPARQL::Algebra::Operator::Reduced}
|
270
313
|
# * {SPARQL::Algebra::Operator::Regex}
|
314
|
+
# * {SPARQL::Algebra::Operator::Replace}
|
315
|
+
# * {SPARQL::Algebra::Operator::Round}
|
271
316
|
# * {SPARQL::Algebra::Operator::SameTerm}
|
317
|
+
# * {SPARQL::Algebra::Operator::Sample}
|
318
|
+
# * {SPARQL::Algebra::Operator::Seconds}
|
319
|
+
# * {SPARQL::Algebra::Operator::SHA1}
|
320
|
+
# * {SPARQL::Algebra::Operator::SHA256}
|
321
|
+
# * {SPARQL::Algebra::Operator::SHA384}
|
322
|
+
# * {SPARQL::Algebra::Operator::SHA512}
|
272
323
|
# * {SPARQL::Algebra::Operator::Slice}
|
273
324
|
# * {SPARQL::Algebra::Operator::Str}
|
325
|
+
# * {SPARQL::Algebra::Operator::StrAfter}
|
326
|
+
# * {SPARQL::Algebra::Operator::StrBefore}
|
327
|
+
# * {SPARQL::Algebra::Operator::StrDT}
|
328
|
+
# * {SPARQL::Algebra::Operator::StrEnds}
|
329
|
+
# * {SPARQL::Algebra::Operator::StrLang}
|
330
|
+
# * {SPARQL::Algebra::Operator::StrLen}
|
331
|
+
# * {SPARQL::Algebra::Operator::StrStarts}
|
332
|
+
# * {SPARQL::Algebra::Operator::StrUUID}
|
333
|
+
# * {SPARQL::Algebra::Operator::SubStr}
|
274
334
|
# * {SPARQL::Algebra::Operator::Subtract}
|
335
|
+
# * {SPARQL::Algebra::Operator::Sum}
|
336
|
+
# * {SPARQL::Algebra::Operator::Table}
|
337
|
+
# * {SPARQL::Algebra::Operator::Timezone}
|
338
|
+
# * {SPARQL::Algebra::Operator::TZ}
|
339
|
+
# * {SPARQL::Algebra::Operator::Ucase}
|
275
340
|
# * {SPARQL::Algebra::Operator::Union}
|
341
|
+
# * {SPARQL::Algebra::Operator::Update}
|
342
|
+
# * {SPARQL::Algebra::Operator::Using}
|
343
|
+
# * {SPARQL::Algebra::Operator::UUID}
|
344
|
+
# * {SPARQL::Algebra::Operator::With}
|
345
|
+
# * {SPARQL::Algebra::Operator::Year}
|
276
346
|
#
|
277
347
|
# TODO
|
278
348
|
# ====
|
279
|
-
# * Need to come up with appropriate SXP for SPARQL 1.1
|
280
349
|
# * Operator#optimize needs to be completed and tested.
|
281
350
|
#
|
282
351
|
# @see http://www.w3.org/TR/rdf-sparql-query/#sparqlAlgebra
|
@@ -288,6 +357,7 @@ module SPARQL
|
|
288
357
|
autoload :Expression, 'sparql/algebra/expression'
|
289
358
|
autoload :Operator, 'sparql/algebra/operator'
|
290
359
|
autoload :Query, 'sparql/algebra/query'
|
360
|
+
autoload :Update, 'sparql/algebra/update'
|
291
361
|
|
292
362
|
##
|
293
363
|
# @example
|
@@ -26,7 +26,7 @@ module SPARQL; module Algebra
|
|
26
26
|
args_enum = solutions.map do |solution|
|
27
27
|
operands.map do |operand|
|
28
28
|
begin
|
29
|
-
operand.evaluate(solution, options.merge(:
|
29
|
+
operand.evaluate(solution, options.merge(depth: options[:depth].to_i + 1))
|
30
30
|
rescue TypeError
|
31
31
|
# Ignore errors
|
32
32
|
nil
|
@@ -14,7 +14,7 @@ module SPARQL; module Algebra
|
|
14
14
|
# @return [RDF::Term]
|
15
15
|
# @abstract
|
16
16
|
def evaluate(bindings, options = {})
|
17
|
-
args = operands.map { |operand| operand.evaluate(bindings, options.merge(:
|
17
|
+
args = operands.map { |operand| operand.evaluate(bindings, options.merge(depth: options[:depth].to_i + 1)) }
|
18
18
|
options[:memoize] ? memoize(*args) : apply(*args)
|
19
19
|
end
|
20
20
|
|
@@ -79,7 +79,7 @@ module SPARQL; module Algebra
|
|
79
79
|
|
80
80
|
##
|
81
81
|
# @example
|
82
|
-
# Expression.new([:isLiteral, RDF::Literal(3.1415)], :
|
82
|
+
# Expression.new([:isLiteral, RDF::Literal(3.1415)], version: 1.0)
|
83
83
|
#
|
84
84
|
# @param [Array] sse
|
85
85
|
# a SPARQL S-Expression (SSE) form
|
@@ -95,12 +95,12 @@ module SPARQL; module Algebra
|
|
95
95
|
return case sse.first
|
96
96
|
when Array
|
97
97
|
debug(options) {"Map array elements #{sse}"}
|
98
|
-
sse.map {|s| self.new(s, options.merge(:
|
98
|
+
sse.map {|s| self.new(s, options.merge(depth: options[:depth].to_i + 1))}
|
99
99
|
else
|
100
100
|
debug(options) {"No operator found for #{sse.first}"}
|
101
101
|
sse.map do |s|
|
102
102
|
s.is_a?(Array) ?
|
103
|
-
self.new(s,
|
103
|
+
self.new(s, depth: options[:depth].to_i + 1) :
|
104
104
|
s
|
105
105
|
end
|
106
106
|
end
|
@@ -110,7 +110,7 @@ module SPARQL; module Algebra
|
|
110
110
|
debug(options) {"Operator=#{operator.inspect}, Operand=#{operand.inspect}"}
|
111
111
|
case operand
|
112
112
|
when Array
|
113
|
-
self.new(operand, options.merge(:
|
113
|
+
self.new(operand, options.merge(depth: options[:depth].to_i + 1))
|
114
114
|
when Operator, Variable, RDF::Term, RDF::Query, Symbol
|
115
115
|
operand
|
116
116
|
when TrueClass, FalseClass, Numeric, String, DateTime, Date, Time
|
@@ -120,7 +120,7 @@ module SPARQL; module Algebra
|
|
120
120
|
end
|
121
121
|
|
122
122
|
debug(options) {"#{operator.inspect}(#{operands.map(&:inspect).join(',')})"}
|
123
|
-
options.delete_if {|k, v| [:debug, :depth, :prefixes, :base_uri].include?(k) }
|
123
|
+
options.delete_if {|k, v| [:debug, :depth, :prefixes, :base_uri, :update].include?(k) }
|
124
124
|
operands << options unless options.empty?
|
125
125
|
operator.new(*operands)
|
126
126
|
end
|
@@ -160,7 +160,7 @@ module SPARQL; module Algebra
|
|
160
160
|
##
|
161
161
|
# Registered extensions
|
162
162
|
#
|
163
|
-
# @return [Hash{RDF
|
163
|
+
# @return [Hash{RDF:URI: Proc}]
|
164
164
|
def self.extensions
|
165
165
|
@extensions ||= {}
|
166
166
|
end
|
@@ -203,22 +203,22 @@ module SPARQL; module Algebra
|
|
203
203
|
when RDF::XSD.dateTime
|
204
204
|
case value
|
205
205
|
when RDF::Literal::DateTime, RDF::Literal::Date, RDF::Literal::Time
|
206
|
-
RDF::Literal.new(value, :
|
206
|
+
RDF::Literal.new(value, datatype: datatype)
|
207
207
|
when RDF::Literal::Numeric, RDF::Literal::Boolean, RDF::URI, RDF::Node
|
208
208
|
raise TypeError, "Value #{value.inspect} cannot be cast as #{datatype}"
|
209
209
|
else
|
210
|
-
RDF::Literal.new(value.value, :
|
210
|
+
RDF::Literal.new(value.value, datatype: datatype, validate: true)
|
211
211
|
end
|
212
212
|
when RDF::XSD.float, RDF::XSD.double
|
213
213
|
case value
|
214
214
|
when RDF::Literal::Boolean
|
215
|
-
RDF::Literal.new(value.object ? 1 : 0, :
|
215
|
+
RDF::Literal.new(value.object ? 1 : 0, datatype: datatype)
|
216
216
|
when RDF::Literal::Numeric
|
217
|
-
RDF::Literal.new(value.to_f, :
|
217
|
+
RDF::Literal.new(value.to_f, datatype: datatype)
|
218
218
|
when RDF::Literal::DateTime, RDF::Literal::Date, RDF::Literal::Time, RDF::URI, RDF::Node
|
219
219
|
raise TypeError, "Value #{value.inspect} cannot be cast as #{datatype}"
|
220
220
|
else
|
221
|
-
RDF::Literal.new(value.value, :
|
221
|
+
RDF::Literal.new(value.value, datatype: datatype, validate: true)
|
222
222
|
end
|
223
223
|
when RDF::XSD.boolean
|
224
224
|
case value
|
@@ -229,21 +229,21 @@ module SPARQL; module Algebra
|
|
229
229
|
when RDF::Literal::DateTime, RDF::Literal::Date, RDF::Literal::Time, RDF::URI, RDF::Node
|
230
230
|
raise TypeError, "Value #{value.inspect} cannot be cast as #{datatype}"
|
231
231
|
else
|
232
|
-
RDF::Literal.new(!value.to_s.empty?, :
|
232
|
+
RDF::Literal.new(!value.to_s.empty?, datatype: datatype, validate: true)
|
233
233
|
end
|
234
234
|
when RDF::XSD.decimal, RDF::XSD.integer
|
235
235
|
case value
|
236
236
|
when RDF::Literal::Boolean
|
237
|
-
RDF::Literal.new(value.object ? 1 : 0, :
|
237
|
+
RDF::Literal.new(value.object ? 1 : 0, datatype: datatype)
|
238
238
|
when RDF::Literal::Integer, RDF::Literal::Decimal
|
239
|
-
RDF::Literal.new(value, :
|
239
|
+
RDF::Literal.new(value, datatype: datatype)
|
240
240
|
when RDF::Literal::DateTime, RDF::Literal::Date, RDF::Literal::Time, RDF::URI, RDF::Node
|
241
241
|
raise TypeError, "Value #{value.inspect} cannot be cast as #{datatype}"
|
242
242
|
else
|
243
|
-
RDF::Literal.new(value.value, :
|
243
|
+
RDF::Literal.new(value.value, datatype: datatype, validate: true)
|
244
244
|
end
|
245
245
|
when RDF::XSD.string
|
246
|
-
RDF::Literal.new(value, :
|
246
|
+
RDF::Literal.new(value, datatype: datatype)
|
247
247
|
else
|
248
248
|
raise TypeError, "Expected datatype (#{datatype}) to be a recognized XPath function"
|
249
249
|
end
|
@@ -260,6 +260,14 @@ module SPARQL; module Algebra
|
|
260
260
|
false
|
261
261
|
end
|
262
262
|
|
263
|
+
##
|
264
|
+
# Returns `false`.
|
265
|
+
#
|
266
|
+
# @return [Boolean]
|
267
|
+
def has_blank_nodes?
|
268
|
+
false
|
269
|
+
end
|
270
|
+
|
263
271
|
##
|
264
272
|
# Returns `true`.
|
265
273
|
#
|