sparql 1.1.5 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
#
|