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
@@ -28,8 +28,8 @@ module SPARQL; module Algebra
|
|
28
28
|
def evaluate(bindings, options = {})
|
29
29
|
queryable = options[:queryable]
|
30
30
|
!operand(0).execute(queryable, options.merge(
|
31
|
-
:
|
32
|
-
:
|
31
|
+
solutions: RDF::Query::Solutions(bindings),
|
32
|
+
depth: options[:depth].to_i + 1)).empty?
|
33
33
|
end
|
34
34
|
end # Exists
|
35
35
|
end # Operator
|
@@ -37,7 +37,7 @@ module SPARQL; module Algebra
|
|
37
37
|
# @return [RDF::Literal::Boolean] `true` or `false`
|
38
38
|
# @raise [TypeError] if the operands could not be coerced to a boolean literal
|
39
39
|
def evaluate(bindings, options = {})
|
40
|
-
res = operands.all? {|op| boolean(op.evaluate(bindings, options.merge(:
|
40
|
+
res = operands.all? {|op| boolean(op.evaluate(bindings, options.merge(depth: options[:depth].to_i + 1))).true? }
|
41
41
|
RDF::Literal(res) # FIXME: error handling
|
42
42
|
end
|
43
43
|
|
@@ -41,14 +41,14 @@ module SPARQL; module Algebra
|
|
41
41
|
# @see http://www.w3.org/TR/rdf-sparql-query/#evaluation
|
42
42
|
def execute(queryable, options = {}, &block)
|
43
43
|
debug(options) {"Extend"}
|
44
|
-
@solutions = operands.last.execute(queryable, options.merge(:
|
44
|
+
@solutions = operands.last.execute(queryable, options.merge(depth: options[:depth].to_i + 1))
|
45
45
|
@solutions.each do |solution|
|
46
46
|
debug(options) {"===> soln #{solution.to_hash.inspect}"}
|
47
47
|
operands.first.each do |(var, expr)|
|
48
48
|
begin
|
49
49
|
val = expr.evaluate(solution, options.merge(
|
50
|
-
:
|
51
|
-
:
|
50
|
+
queryable: queryable,
|
51
|
+
depth: options[:depth].to_i + 1))
|
52
52
|
debug(options) {"===> + #{var} => #{val.inspect}"}
|
53
53
|
solution.bindings[var.to_sym] = val
|
54
54
|
rescue TypeError => e
|
@@ -38,9 +38,9 @@ module SPARQL; module Algebra
|
|
38
38
|
# @see http://www.w3.org/TR/rdf-sparql-query/#ebv
|
39
39
|
def execute(queryable, options = {}, &block)
|
40
40
|
debug(options) {"Filter #{operands.first.to_sxp}"}
|
41
|
-
opts = options.merge(:
|
41
|
+
opts = options.merge(queryable: queryable, depth: options[:depth].to_i + 1)
|
42
42
|
@solutions = RDF::Query::Solutions()
|
43
|
-
queryable.query(operands.last, options.merge(:
|
43
|
+
queryable.query(operands.last, options.merge(depth: options[:depth].to_i + 1)) do |solution|
|
44
44
|
begin
|
45
45
|
pass = boolean(operands.first.evaluate(solution, opts)).true?
|
46
46
|
debug(options) {"(filter) #{pass.inspect} #{solution.to_hash.inspect}"}
|
@@ -4,22 +4,55 @@ module SPARQL; module Algebra
|
|
4
4
|
##
|
5
5
|
# The SPARQL GraphPattern `graph` operator.
|
6
6
|
#
|
7
|
-
# This is a wrapper to add a `context` to the query.
|
7
|
+
# This is a wrapper to add a `context` to the query, or an array of statements.
|
8
8
|
#
|
9
|
-
# @example
|
9
|
+
# @example of a query
|
10
10
|
# (prefix ((: <http://example/>))
|
11
11
|
# (graph ?g
|
12
12
|
# (bgp (triple ?s ?p ?o))))
|
13
13
|
#
|
14
|
+
# @example named set of statements
|
15
|
+
# (prefix ((: <http://example/>))
|
16
|
+
# (graph :g
|
17
|
+
# ((triple :s :p :o))))
|
18
|
+
#
|
14
19
|
# @see http://www.w3.org/TR/rdf-sparql-query/#sparqlAlgebra
|
15
20
|
class Graph < Operator::Binary
|
16
21
|
include Query
|
17
22
|
|
18
23
|
NAME = [:graph]
|
24
|
+
##
|
25
|
+
# A `graph` is an RDF::Query with a context. It can also be used as a container of statements or patterns, or other queryable operators (see GraphGraphPattern)
|
26
|
+
#
|
27
|
+
# @overload self.new(name, bgp)
|
28
|
+
# @param [RDF::Resource] name
|
29
|
+
# @param [RDF::Query] patterns
|
30
|
+
# A sub-query (bgp)
|
31
|
+
# @overload self.new(name, bgp)
|
32
|
+
# @param [RDF::Resource] name
|
33
|
+
# @param [Operator] patterns
|
34
|
+
# A sub-query (GraphGraphPattern)
|
35
|
+
# @overload self.new(name, patterns)
|
36
|
+
# @param [RDF::Resource] name
|
37
|
+
# @param [Array<RDF::Query::Pattern>] patterns
|
38
|
+
# Quads
|
39
|
+
# @return [RDF::Query]
|
40
|
+
def self.new(name, patterns, &block)
|
41
|
+
case patterns
|
42
|
+
when RDF::Query
|
43
|
+
# Record that the argument as a (bgp) for re-serialization back to SSE
|
44
|
+
RDF::Query.new(*(patterns.patterns + [{context: name,}]), &block)
|
45
|
+
when Operator
|
46
|
+
super
|
47
|
+
else
|
48
|
+
RDF::Query.new(*(patterns + [{context: name, as_container: true}]), &block)
|
49
|
+
end
|
50
|
+
end
|
19
51
|
|
20
52
|
##
|
21
|
-
#
|
22
|
-
#
|
53
|
+
# If the second operand is a Query operator:
|
54
|
+
# Executes this query on the given `queryable` graph or repository.
|
55
|
+
# Applies the given `context` to the query, limiting the scope of the query to the specified `context`, which may be an `RDF::URI` or `RDF::Query::Variable`.
|
23
56
|
#
|
24
57
|
# @param [RDF::Queryable] queryable
|
25
58
|
# the graph or repository to query
|
@@ -35,7 +68,7 @@ module SPARQL; module Algebra
|
|
35
68
|
def execute(queryable, options = {}, &block)
|
36
69
|
debug(options) {"Graph #{operands.first}"}
|
37
70
|
context, query = operands.first, operands.last
|
38
|
-
@solutions = queryable.query(query, options.merge(:
|
71
|
+
@solutions = queryable.query(query, options.merge(context: context), &block)
|
39
72
|
end
|
40
73
|
|
41
74
|
##
|
@@ -50,6 +83,7 @@ module SPARQL; module Algebra
|
|
50
83
|
|
51
84
|
##
|
52
85
|
# Don't do any more rewriting
|
86
|
+
# FIXME: if ooperator is JOIN, and rewritten sub-operators are queries, can do simple merge of sub-graphs
|
53
87
|
# @return [SPARQL::Algebra::Expression] `self`
|
54
88
|
def rewrite(&block)
|
55
89
|
self
|
@@ -43,7 +43,7 @@ module SPARQL; module Algebra
|
|
43
43
|
exprlist = operands.first
|
44
44
|
query = operands.last
|
45
45
|
aggregates = operands.length == 3 ? operand(1) : []
|
46
|
-
solutions = queryable.query(query, options.merge(:
|
46
|
+
solutions = queryable.query(query, options.merge(depth: options[:depth].to_i + 1))
|
47
47
|
|
48
48
|
groups = solutions.group_by do |solution|
|
49
49
|
# Evaluate each exprlist operand to get groups where each key is a new solution
|
@@ -55,13 +55,13 @@ module SPARQL; module Algebra
|
|
55
55
|
# Form is [variable, expression]
|
56
56
|
soln[operand.first] = operand.last.evaluate(solution,
|
57
57
|
options.merge(
|
58
|
-
:
|
59
|
-
:
|
58
|
+
queryable: queryable,
|
59
|
+
depth: options[:depth].to_i + 1))
|
60
60
|
else
|
61
61
|
# Form is variable
|
62
62
|
soln[operand] = operand.evaluate(solution, options.merge(
|
63
|
-
:
|
64
|
-
:
|
63
|
+
queryable: queryable,
|
64
|
+
depth: options[:depth].to_i + 1))
|
65
65
|
end
|
66
66
|
rescue TypeError
|
67
67
|
# Ignore expression
|
@@ -30,7 +30,7 @@ module SPARQL; module Algebra
|
|
30
30
|
sep = operands.length == 2 ? operand(0).last : RDF::Literal(' ')
|
31
31
|
args_enum = solutions.map do |solution|
|
32
32
|
begin
|
33
|
-
operands.last.evaluate(solution, options.merge(:
|
33
|
+
operands.last.evaluate(solution, options.merge(depth: options[:depth].to_i + 1))
|
34
34
|
rescue TypeError
|
35
35
|
# Ignore errors
|
36
36
|
nil
|
@@ -34,9 +34,9 @@ module SPARQL; module Algebra
|
|
34
34
|
# @return [RDF::Term]
|
35
35
|
# @raise [TypeError]
|
36
36
|
def evaluate(bindings, options = {})
|
37
|
-
operand(0).evaluate(bindings, options.merge(:
|
38
|
-
operand(1).evaluate(bindings, options.merge(:
|
39
|
-
operand(2).evaluate(bindings, options.merge(:
|
37
|
+
operand(0).evaluate(bindings, options.merge(depth: options[:depth].to_i + 1)) == RDF::Literal::TRUE ?
|
38
|
+
operand(1).evaluate(bindings, options.merge(depth: options[:depth].to_i + 1).merge(depth: options[:depth].to_i + 1)) :
|
39
|
+
operand(2).evaluate(bindings, options.merge(depth: options[:depth].to_i + 1))
|
40
40
|
rescue
|
41
41
|
raise TypeError
|
42
42
|
end
|
@@ -45,7 +45,7 @@ module SPARQL; module Algebra
|
|
45
45
|
error_found = false
|
46
46
|
found = operands[1..-1].any? do |op|
|
47
47
|
begin
|
48
|
-
lhs == op.evaluate(bindings, options.merge(:
|
48
|
+
lhs == op.evaluate(bindings, options.merge(depth: options[:depth].to_i + 1))
|
49
49
|
rescue TypeError
|
50
50
|
error_found = true
|
51
51
|
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
|
4
|
+
##
|
5
|
+
# The SPARQL UPDATE `insertData` operator.
|
6
|
+
#
|
7
|
+
# The INSERT operation is a form of the DELETE/INSERT operation having no DELETE section
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# (insert ((triple ?s ?p "q")))
|
11
|
+
#
|
12
|
+
# @see http://www.w3.org/TR/sparql11-update/#insert
|
13
|
+
class Insert < Operator::Unary
|
14
|
+
include SPARQL::Algebra::Update
|
15
|
+
|
16
|
+
NAME = [:insert]
|
17
|
+
|
18
|
+
##
|
19
|
+
# Executes this upate on the given `writable` graph or repository.
|
20
|
+
#
|
21
|
+
# @param [RDF::Queryable] queryable
|
22
|
+
# the graph or repository to write
|
23
|
+
# @param [RDF::Query::Solution] solution
|
24
|
+
# Solution to map to patterns for this operation
|
25
|
+
# @param [Hash{Symbol => Object}] options
|
26
|
+
# any additional keyword options
|
27
|
+
# @option options [Boolean] debug
|
28
|
+
# Query execution debugging
|
29
|
+
# @return [RDF::Queryable]
|
30
|
+
# Returns queryable.
|
31
|
+
# @raise [IOError]
|
32
|
+
# If `from` does not exist, unless the `silent` operator is present
|
33
|
+
# @see http://www.w3.org/TR/sparql11-update/
|
34
|
+
def execute(queryable, solution, options = {})
|
35
|
+
debug(options) {"Insert"}
|
36
|
+
patterns = operand.inject([]) do |memo, op|
|
37
|
+
if op.respond_to?(:statements)
|
38
|
+
memo += op.statements.to_a
|
39
|
+
else
|
40
|
+
memo << op
|
41
|
+
end
|
42
|
+
memo
|
43
|
+
end
|
44
|
+
patterns.each do |pattern|
|
45
|
+
pattern = pattern.dup.bind(solution)
|
46
|
+
debug(options) {"Insert statement #{statement.to_sse}"}
|
47
|
+
# Only insert bound or constant patterns
|
48
|
+
queryable.insert(RDF::Statement.from(pattern)) if pattern.bound? || pattern.constant?
|
49
|
+
end
|
50
|
+
queryable
|
51
|
+
end
|
52
|
+
end # Insert
|
53
|
+
end # Operator
|
54
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
|
4
|
+
##
|
5
|
+
# The SPARQL UPDATE `insertData` operator.
|
6
|
+
#
|
7
|
+
# The INSERT DATA operation adds some triples, given inline in the request, into the Graph Store
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# (insertData ((graph <http://example.org/g1> ((triple :s :p :o)))))
|
11
|
+
#
|
12
|
+
# @see http://www.w3.org/TR/sparql11-update/#insertData
|
13
|
+
class InsertData < Operator::Unary
|
14
|
+
include SPARQL::Algebra::Update
|
15
|
+
|
16
|
+
NAME = [:insertData]
|
17
|
+
|
18
|
+
##
|
19
|
+
# Executes this upate on the given `writable` graph or repository.
|
20
|
+
#
|
21
|
+
# @param [RDF::Queryable] queryable
|
22
|
+
# the graph or repository to write
|
23
|
+
# @param [Hash{Symbol => Object}] options
|
24
|
+
# any additional keyword options
|
25
|
+
# @option options [Boolean] debug
|
26
|
+
# Query execution debugging
|
27
|
+
# @return [RDF::Queryable]
|
28
|
+
# Returns queryable.
|
29
|
+
# @raise [IOError]
|
30
|
+
# If `from` does not exist, unless the `silent` operator is present
|
31
|
+
# @see http://www.w3.org/TR/sparql11-update/
|
32
|
+
def execute(queryable, options = {})
|
33
|
+
operand.each do |op|
|
34
|
+
debug(options) {"InsertData #{op.to_sxp}"}
|
35
|
+
queryable.insert(op)
|
36
|
+
end
|
37
|
+
queryable
|
38
|
+
end
|
39
|
+
end # InsertData
|
40
|
+
end # Operator
|
41
|
+
end; end # SPARQL::Algebra
|
@@ -41,10 +41,10 @@ module SPARQL; module Algebra
|
|
41
41
|
# Generate solutions independently, merge based on solution compatibility
|
42
42
|
debug(options) {"Join"}
|
43
43
|
|
44
|
-
left = queryable.query(operand(0), options.merge(:
|
44
|
+
left = queryable.query(operand(0), options.merge(depth: options[:depth].to_i + 1))
|
45
45
|
debug(options) {"(join)=>(left) #{left.inspect}"}
|
46
46
|
|
47
|
-
right = queryable.query(operand(1), options.merge(:
|
47
|
+
right = queryable.query(operand(1), options.merge(depth: options[:depth].to_i + 1))
|
48
48
|
debug(options) {"(join)=>(right) #{right.inspect}"}
|
49
49
|
|
50
50
|
@solutions = RDF::Query::Solutions(left.map do |s1|
|
@@ -22,7 +22,7 @@ module SPARQL; module Algebra
|
|
22
22
|
# @raise [TypeError] if the operand is not a literal value
|
23
23
|
def apply(operand)
|
24
24
|
case operand
|
25
|
-
when RDF::Literal then RDF::Literal(operand.to_s.downcase, :
|
25
|
+
when RDF::Literal then RDF::Literal(operand.to_s.downcase, datatype: operand.datatype, language: operand.language)
|
26
26
|
else raise TypeError, "expected an RDF::Literal::Numeric, but got #{operand.inspect}"
|
27
27
|
end
|
28
28
|
end
|
@@ -38,10 +38,10 @@ module SPARQL; module Algebra
|
|
38
38
|
filter = operand(2)
|
39
39
|
|
40
40
|
debug(options) {"LeftJoin"}
|
41
|
-
left = queryable.query(operand(0), options.merge(:
|
41
|
+
left = queryable.query(operand(0), options.merge(depth: options[:depth].to_i + 1))
|
42
42
|
debug(options) {"=>(leftjoin left) #{left.inspect}"}
|
43
43
|
|
44
|
-
right = queryable.query(operand(1), options.merge(:
|
44
|
+
right = queryable.query(operand(1), options.merge(depth: options[:depth].to_i + 1))
|
45
45
|
debug(options) {"=>(leftjoin right) #{right.inspect}"}
|
46
46
|
|
47
47
|
# LeftJoin(Ω1, Ω2, expr) =
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
|
4
|
+
##
|
5
|
+
# The SPARQL UPDATE `load` operator.
|
6
|
+
#
|
7
|
+
# The LOAD operation reads an RDF document from a IRI and inserts its triples into the specified graph in the Graph Store. The specified destination graph should be created if required; again, implementations providing an update service over a fixed set of graphs must return with failure for a request that would create a disallowed graph. If the destination graph already exists, then no data in that graph will be removed.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# (load <remote> <g>)
|
11
|
+
#
|
12
|
+
# @see http://www.w3.org/TR/sparql11-update/#load
|
13
|
+
class Load < Operator
|
14
|
+
include SPARQL::Algebra::Update
|
15
|
+
|
16
|
+
NAME = [:load]
|
17
|
+
|
18
|
+
##
|
19
|
+
# Executes this upate on the given `writable` graph or repository.
|
20
|
+
#
|
21
|
+
# @param [RDF::Queryable] queryable
|
22
|
+
# the graph or repository to write
|
23
|
+
# @param [Hash{Symbol => Object}] options
|
24
|
+
# any additional keyword options
|
25
|
+
# @option options [Boolean] debug
|
26
|
+
# Query execution debugging
|
27
|
+
# @return [RDF::Queryable]
|
28
|
+
# Returns queryable.
|
29
|
+
# @raise [IOError]
|
30
|
+
# If `from` does not exist, unless the `silent` operator is present
|
31
|
+
# @see http://www.w3.org/TR/sparql11-update/
|
32
|
+
def execute(queryable, options = {})
|
33
|
+
debug(options) {"Load"}
|
34
|
+
silent = operands.first == :silent
|
35
|
+
operands.shift if silent
|
36
|
+
|
37
|
+
raise ArgumentError, "load expected one or two operands, got #{operands.length}" unless [1,2].include?(operands.length)
|
38
|
+
|
39
|
+
location, name = operands
|
40
|
+
queryable.load(location, context: name)
|
41
|
+
rescue IOError, Errno::ENOENT
|
42
|
+
raise unless silent
|
43
|
+
ensure
|
44
|
+
queryable
|
45
|
+
end
|
46
|
+
end # Load
|
47
|
+
end # Operator
|
48
|
+
end; end # SPARQL::Algebra
|
@@ -42,9 +42,9 @@ module SPARQL; module Algebra
|
|
42
42
|
#
|
43
43
|
# card[Minus(Ω1, Ω2)](μ) = card[Ω1](μ)
|
44
44
|
debug(options) {"Minus"}
|
45
|
-
left = queryable.query(operand(0), options.merge(:
|
45
|
+
left = queryable.query(operand(0), options.merge(depth: options[:depth].to_i + 1))
|
46
46
|
debug(options) {"(minus left) #{left.inspect}"}
|
47
|
-
right = queryable.query(operand(1), options.merge(:
|
47
|
+
right = queryable.query(operand(1), options.merge(depth: options[:depth].to_i + 1))
|
48
48
|
debug(options) {"(minus right) #{right.inspect}"}
|
49
49
|
@solutions = left.minus(right)
|
50
50
|
@solutions.each(&block) if block_given?
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
|
4
|
+
##
|
5
|
+
# The SPARQL UPDATE `modify` operator.
|
6
|
+
#
|
7
|
+
# Wraps delete/insert
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# (modify
|
11
|
+
# (bgp (triple ?a foaf:knows ?b))
|
12
|
+
# (delete ((triple ?a foaf:knows ?b)))
|
13
|
+
# (insert ((triple ?b foaf:knows ?a)))
|
14
|
+
#
|
15
|
+
# @see XXX
|
16
|
+
class Modify < Operator
|
17
|
+
include SPARQL::Algebra::Update
|
18
|
+
|
19
|
+
NAME = [:modify]
|
20
|
+
|
21
|
+
##
|
22
|
+
# Executes this upate on the given `writable` graph or repository.
|
23
|
+
#
|
24
|
+
# Execute the first operand to get solutions, and apply those solutions to the subsequent operators.
|
25
|
+
#
|
26
|
+
# @param [RDF::Queryable] queryable
|
27
|
+
# the graph or repository to write
|
28
|
+
# @param [Hash{Symbol => Object}] options
|
29
|
+
# any additional keyword options
|
30
|
+
# @option options [Boolean] debug
|
31
|
+
# Query execution debugging
|
32
|
+
# @return [RDF::Queryable]
|
33
|
+
# Returns queryable.
|
34
|
+
# @raise [IOError]
|
35
|
+
# If `from` does not exist, unless the `silent` operator is present
|
36
|
+
# @see http://www.w3.org/TR/sparql11-update/
|
37
|
+
def execute(queryable, options = {})
|
38
|
+
debug(options) {"Modify"}
|
39
|
+
query = operands.shift
|
40
|
+
|
41
|
+
queryable.query(query, options.merge(depth: options[:depth].to_i + 1)) do |solution|
|
42
|
+
debug(options) {"(solution)=>#{solution.inspect}"}
|
43
|
+
|
44
|
+
# Execute each operand with queryable and solution
|
45
|
+
operands.each do |op|
|
46
|
+
op.execute(queryable, solution, options.merge(depth: options[:depth].to_i + 1))
|
47
|
+
end
|
48
|
+
end
|
49
|
+
queryable
|
50
|
+
end
|
51
|
+
end # Modify
|
52
|
+
end # Operator
|
53
|
+
end; end # SPARQL::Algebra
|