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
@@ -0,0 +1,67 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
|
4
|
+
##
|
5
|
+
# The SPARQL UPDATE `move` operator.
|
6
|
+
#
|
7
|
+
# The MOVE operation is a shortcut for moving all data from an input graph into a destination graph. The input graph is removed after insertion and data from the destination graph, if any, is removed before insertion.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# (move silent <iri> to default)
|
11
|
+
#
|
12
|
+
# @see http://www.w3.org/TR/sparql11-update/#move
|
13
|
+
class Move < Operator
|
14
|
+
include SPARQL::Algebra::Update
|
15
|
+
|
16
|
+
NAME = [:move]
|
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) {"Move"}
|
34
|
+
silent = operands.first == :silent
|
35
|
+
operands.shift if silent
|
36
|
+
|
37
|
+
src_name, dest_name = operands[-2..-1]
|
38
|
+
raise ArgumentError, "move expected two operands, got #{operands.length}" unless operands.length == 2
|
39
|
+
raise ArgumentError, "move from must be IRI or :default" unless src_name == :default || src_name.is_a?(RDF::URI)
|
40
|
+
raise ArgumentError, "move to must be IRI or :default" unless dest_name == :default || dest_name.is_a?(RDF::URI)
|
41
|
+
src = queryable.enum_graph.detect {|g| g.to_s == src_name.to_s}
|
42
|
+
|
43
|
+
if src.nil?
|
44
|
+
raise IOError, "move operation source does not exist" unless silent
|
45
|
+
elsif dest_name == src_name
|
46
|
+
# No operation
|
47
|
+
else
|
48
|
+
dest = queryable.enum_graph.detect {|g| g.to_s == dest_name.to_s}
|
49
|
+
|
50
|
+
# Clear destination first
|
51
|
+
dest.clear! if dest
|
52
|
+
|
53
|
+
# Copy statements using destination context
|
54
|
+
src.each do |statement|
|
55
|
+
statement = statement.dup
|
56
|
+
statement.context = (dest_name unless dest_name == :default)
|
57
|
+
queryable << statement
|
58
|
+
end
|
59
|
+
|
60
|
+
# Clear source
|
61
|
+
src.clear!
|
62
|
+
end
|
63
|
+
queryable
|
64
|
+
end
|
65
|
+
end # Move
|
66
|
+
end # Operator
|
67
|
+
end; end # SPARQL::Algebra
|
@@ -30,7 +30,7 @@ module SPARQL; module Algebra
|
|
30
30
|
def evaluate(bindings, options = {})
|
31
31
|
solutions = RDF::Query::Solutions(bindings)
|
32
32
|
queryable = options[:queryable]
|
33
|
-
operand(0).execute(queryable, options.merge(:
|
33
|
+
operand(0).execute(queryable, options.merge(solutions: solutions)).empty?
|
34
34
|
end
|
35
35
|
end # NotExists
|
36
36
|
end # Operator
|
@@ -43,11 +43,11 @@ module SPARQL; module Algebra
|
|
43
43
|
# @return [RDF::Literal::Boolean] `true` or `false`
|
44
44
|
# @raise [TypeError] if term is not found and any operand raises an error
|
45
45
|
def evaluate(bindings, options = {})
|
46
|
-
lhs = operands.first.evaluate(bindings, options.merge(:
|
46
|
+
lhs = operands.first.evaluate(bindings, options.merge(depth: options[:depth].to_i + 1))
|
47
47
|
error_found = false
|
48
48
|
found = operands[1..-1].any? do |op|
|
49
49
|
begin
|
50
|
-
lhs == op.evaluate(bindings, options.merge(:
|
50
|
+
lhs == op.evaluate(bindings, options.merge(depth: options[:depth].to_i + 1))
|
51
51
|
rescue TypeError
|
52
52
|
error_found = true
|
53
53
|
end
|
@@ -42,13 +42,13 @@ module SPARQL; module Algebra
|
|
42
42
|
# @raise [TypeError] if the operands could not be coerced to a boolean literal
|
43
43
|
def evaluate(bindings, options = {})
|
44
44
|
begin
|
45
|
-
left = boolean(operand(0).evaluate(bindings, options.merge(:
|
45
|
+
left = boolean(operand(0).evaluate(bindings, options.merge(depth: options[:depth].to_i + 1))).true?
|
46
46
|
rescue TypeError
|
47
47
|
left = nil
|
48
48
|
end
|
49
49
|
|
50
50
|
begin
|
51
|
-
right = boolean(operand(1).evaluate(bindings, options.merge(:
|
51
|
+
right = boolean(operand(1).evaluate(bindings, options.merge(depth: options[:depth].to_i + 1))).true?
|
52
52
|
rescue TypeError
|
53
53
|
right = nil
|
54
54
|
end
|
@@ -34,12 +34,12 @@ module SPARQL; module Algebra
|
|
34
34
|
def execute(queryable, options = {}, &block)
|
35
35
|
|
36
36
|
debug(options) {"Order"}
|
37
|
-
@solutions = queryable.query(operands.last, options.merge(:
|
37
|
+
@solutions = queryable.query(operands.last, options.merge(depth: options[:depth].to_i + 1)).order do |a, b|
|
38
38
|
operand(0).inject(0) do |memo, op|
|
39
39
|
debug(options) {"(order) #{op.inspect}"}
|
40
40
|
memo = begin
|
41
|
-
a_eval = op.evaluate(a, options.merge(:
|
42
|
-
b_eval = op.evaluate(b, options.merge(:
|
41
|
+
a_eval = op.evaluate(a, options.merge(queryable: queryable, depth: options[:depth].to_i + 1)) rescue nil
|
42
|
+
b_eval = op.evaluate(b, options.merge(queryable: queryable, depth: options[:depth].to_i + 1)) rescue nil
|
43
43
|
comp = Operator::Compare.evaluate(a_eval, b_eval).to_i
|
44
44
|
comp = -comp if op.is_a?(Operator::Desc)
|
45
45
|
comp
|
@@ -1,29 +1,35 @@
|
|
1
1
|
module SPARQL; module Algebra
|
2
2
|
class Operator
|
3
3
|
##
|
4
|
-
# The SPARQL numeric unary `+` operator.
|
4
|
+
# The SPARQL numeric binary/unary `+` operator.
|
5
5
|
#
|
6
6
|
# @example
|
7
7
|
# (+ ?x ?y)
|
8
8
|
# (plus ?x ?y)
|
9
9
|
#
|
10
10
|
# @see http://www.w3.org/TR/xpath-functions/#func-numeric-unary-plus
|
11
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-numeric-add
|
11
12
|
class Plus < Operator::Unary
|
12
13
|
include Evaluatable
|
13
14
|
|
14
15
|
NAME = [:+, :plus]
|
15
16
|
|
16
17
|
##
|
17
|
-
# Returns the
|
18
|
+
# Returns the arithmetic sum of the operands, unless there is no `right`.
|
18
19
|
#
|
19
|
-
# @param [RDF::Literal::Numeric]
|
20
|
+
# @param [RDF::Literal::Numeric] left
|
21
|
+
# a numeric literal
|
22
|
+
# @param [RDF::Literal::Numeric] right
|
20
23
|
# a numeric literal
|
21
24
|
# @return [RDF::Literal::Numeric]
|
22
|
-
# @raise [TypeError] if
|
23
|
-
def apply(
|
24
|
-
case
|
25
|
-
|
26
|
-
|
25
|
+
# @raise [TypeError] if either operand is not a numeric literal
|
26
|
+
def apply(left, right = nil)
|
27
|
+
case
|
28
|
+
when left.is_a?(RDF::Literal::Numeric) && right.is_a?(RDF::Literal::Numeric)
|
29
|
+
left + right
|
30
|
+
when left.is_a?(RDF::Literal::Numeric) && right.nil?
|
31
|
+
left
|
32
|
+
else raise TypeError, "expected two RDF::Literal::Numeric operands, but got #{left.inspect} and #{right.inspect}"
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end # Plus
|
@@ -32,7 +32,7 @@ module SPARQL; module Algebra
|
|
32
32
|
# @see http://www.w3.org/TR/rdf-sparql-query/#sparqlAlgebra
|
33
33
|
def execute(queryable, options = {}, &block)
|
34
34
|
debug(options) {"Prefix"}
|
35
|
-
@solutions = queryable.query(operands.last, options.merge(:
|
35
|
+
@solutions = queryable.query(operands.last, options.merge(depth: options[:depth].to_i + 1), &block)
|
36
36
|
end
|
37
37
|
|
38
38
|
##
|
@@ -31,7 +31,7 @@ module SPARQL; module Algebra
|
|
31
31
|
# the resulting solution sequence
|
32
32
|
# @see http://www.w3.org/TR/rdf-sparql-query/#sparqlAlgebra
|
33
33
|
def execute(queryable, options = {}, &block)
|
34
|
-
@solutions = queryable.query(operands.last, options.merge(:
|
34
|
+
@solutions = queryable.query(operands.last, options.merge(depth: options[:depth].to_i + 1))
|
35
35
|
@solutions = @solutions.project(*(operands.first))
|
36
36
|
@solutions.each(&block) if block_given?
|
37
37
|
@solutions
|
@@ -33,7 +33,7 @@ module SPARQL; module Algebra
|
|
33
33
|
# @see http://www.w3.org/TR/rdf-sparql-query/#sparqlAlgebra
|
34
34
|
def execute(queryable, options = {}, &block)
|
35
35
|
@solutions = operands.last.
|
36
|
-
execute(queryable, options.merge(:
|
36
|
+
execute(queryable, options.merge(depth: options[:depth].to_i + 1)).reduced
|
37
37
|
@solutions.each(&block) if block_given?
|
38
38
|
@solutions
|
39
39
|
end
|
@@ -63,7 +63,7 @@ module SPARQL; module Algebra
|
|
63
63
|
options |= Regexp::MULTILINE if flags.include?(?m)
|
64
64
|
options |= Regexp::IGNORECASE if flags.include?(?i)
|
65
65
|
options |= Regexp::EXTENDED if flags.include?(?x)
|
66
|
-
RDF::Literal(text.to_s.gsub(Regexp.new(pattern, options), replacement), :
|
66
|
+
RDF::Literal(text.to_s.gsub(Regexp.new(pattern, options), replacement), datatype: text.datatype, language: text.language)
|
67
67
|
end
|
68
68
|
|
69
69
|
##
|
@@ -46,7 +46,7 @@ module SPARQL; module Algebra
|
|
46
46
|
def execute(queryable, options = {}, &block)
|
47
47
|
offset = operands[0] == :_ ? 0 : operands[0].to_i
|
48
48
|
limit = operands[1] == :_ ? -1 : operands[1].to_i
|
49
|
-
@solutions = operands.last. execute(queryable, options.merge(:
|
49
|
+
@solutions = operands.last. execute(queryable, options.merge(depth: options[:depth].to_i + 1))
|
50
50
|
@solutions.offset(operands[0]) unless operands[0] == :_
|
51
51
|
@solutions.limit(operands[1]) unless operands[1] == :_
|
52
52
|
@solutions.each(&block) if block_given?
|
@@ -49,7 +49,7 @@ module SPARQL; module Algebra
|
|
49
49
|
RDF::Literal("")
|
50
50
|
else
|
51
51
|
parts = left.to_s.split(right.to_s)
|
52
|
-
RDF::Literal(parts.last, :
|
52
|
+
RDF::Literal(parts.last, datatype: left.datatype, language: left.language)
|
53
53
|
end
|
54
54
|
end
|
55
55
|
end # StrAfter
|
@@ -45,13 +45,13 @@ module SPARQL; module Algebra
|
|
45
45
|
raise TypeError, "expected two RDF::Literal operands, but got #{left.inspect} and #{right.inspect}"
|
46
46
|
when right.to_s.empty?
|
47
47
|
# If the lexical form of arg2 is the empty string, this is considered to be a match and the lexical form of the result is is the empty string.
|
48
|
-
RDF::Literal("", :
|
48
|
+
RDF::Literal("", language: left.language, datatype: left.datatype)
|
49
49
|
when !left.to_s.include?(right.to_s)
|
50
50
|
# If the lexical form of arg2 is the empty string, this is considered to be a match and the lexical form of the result is is the empty string.
|
51
51
|
RDF::Literal("")
|
52
52
|
else
|
53
53
|
parts = left.to_s.split(right.to_s)
|
54
|
-
RDF::Literal(parts.first, :
|
54
|
+
RDF::Literal(parts.first, language: left.language, datatype: left.datatype)
|
55
55
|
end
|
56
56
|
end
|
57
57
|
end # StrBefore
|
@@ -26,7 +26,7 @@ module SPARQL; module Algebra
|
|
26
26
|
# @see http://www.w3.org/TR/sparql11-query/#func-strdt
|
27
27
|
def apply(value, datatypeIRI)
|
28
28
|
raise TypeError, "Literal #{value.inspect} is not simple" unless value.simple?
|
29
|
-
RDF::Literal.new(value.to_s, :
|
29
|
+
RDF::Literal.new(value.to_s, datatype: datatypeIRI)
|
30
30
|
end
|
31
31
|
end # StrDT
|
32
32
|
end # Operator
|
@@ -27,7 +27,7 @@ module SPARQL; module Algebra
|
|
27
27
|
# @see http://www.w3.org/TR/sparql11-query/#func-strlang
|
28
28
|
def apply(value, langTag)
|
29
29
|
raise TypeError, "Literal #{value.inspect} is not simple" unless value.simple?
|
30
|
-
RDF::Literal.new(value.to_s, :
|
30
|
+
RDF::Literal.new(value.to_s, language: langTag.to_s)
|
31
31
|
end
|
32
32
|
end # StrLang
|
33
33
|
end # Operator
|
@@ -57,11 +57,11 @@ module SPARQL; module Algebra
|
|
57
57
|
startingLoc = startingLoc.to_i
|
58
58
|
|
59
59
|
if length == RDF::Literal("")
|
60
|
-
RDF::Literal(source.to_s[(startingLoc-1)..-1], :
|
60
|
+
RDF::Literal(source.to_s[(startingLoc-1)..-1], datatype: source.datatype, language: source.language)
|
61
61
|
else
|
62
62
|
raise TypeError, "expected an integer, but got #{length.inspect}" unless length.is_a?(RDF::Literal::Integer)
|
63
63
|
length = length.to_i
|
64
|
-
RDF::Literal(source.to_s[(startingLoc-1), length], :
|
64
|
+
RDF::Literal(source.to_s[(startingLoc-1), length], datatype: source.datatype, language: source.language)
|
65
65
|
end
|
66
66
|
end
|
67
67
|
|
@@ -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.upcase, :
|
25
|
+
when RDF::Literal then RDF::Literal(operand.to_s.upcase, 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
|
@@ -34,7 +34,7 @@ module SPARQL; module Algebra
|
|
34
34
|
def execute(queryable, options = {}, &block)
|
35
35
|
debug(options) {"Union"}
|
36
36
|
@solutions = RDF::Query::Solutions(operands.inject([]) do |memo, op|
|
37
|
-
solns = op.execute(queryable, options.merge(:
|
37
|
+
solns = op.execute(queryable, options.merge(depth: options[:depth].to_i + 1))
|
38
38
|
debug(options) {"=> (op) #{solns.inspect}"}
|
39
39
|
memo + solns
|
40
40
|
end)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL GraphPattern `prefix` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (update
|
8
|
+
# (modify
|
9
|
+
# (bgp (triple ?s ?p ?o))
|
10
|
+
# (insert ((triple ?s ?p "q")))))
|
11
|
+
#
|
12
|
+
# @see http://www.w3.org/TR/sparql11-update/#graphUpdate
|
13
|
+
class Update < Operator
|
14
|
+
include SPARQL::Algebra::Update
|
15
|
+
|
16
|
+
NAME = [:update]
|
17
|
+
|
18
|
+
##
|
19
|
+
# Executes this upate on the given `queryable` 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 the dataset.
|
29
|
+
# @raise [NotImplementedError]
|
30
|
+
# If an attempt is made to perform an unsupported operation
|
31
|
+
# @raise [IOError]
|
32
|
+
# If `queryable` is immutable
|
33
|
+
# @see http://www.w3.org/TR/sparql11-update/
|
34
|
+
def execute(queryable, options = {})
|
35
|
+
debug(options) {"Update"}
|
36
|
+
raise IOError, "queryable is not mutable" unless queryable.mutable?
|
37
|
+
operands.each do |op|
|
38
|
+
op.execute(queryable, options.merge(depth: options[:depth].to_i + 1))
|
39
|
+
end
|
40
|
+
queryable
|
41
|
+
end
|
42
|
+
end # Update
|
43
|
+
end # Operator
|
44
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
|
4
|
+
##
|
5
|
+
# The SPARQL UPDATE `using` operator.
|
6
|
+
#
|
7
|
+
# The USING and USING NAMED clauses affect the RDF Dataset used while evaluating the WHERE clause. This describes a dataset in the same way as FROM and FROM NAMED clauses describe RDF Datasets in the SPARQL 1.1 Query Language
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# (using (:g1) (bgp (triple ?s ?p ?o)))
|
11
|
+
#
|
12
|
+
# @see http://www.w3.org/TR/sparql11-update/#add
|
13
|
+
class Using < Operator
|
14
|
+
include SPARQL::Algebra::Query
|
15
|
+
|
16
|
+
NAME = :using
|
17
|
+
|
18
|
+
##
|
19
|
+
# Executes this upate on the given `writable` graph or repository.
|
20
|
+
#
|
21
|
+
# Delegates to Dataset
|
22
|
+
#
|
23
|
+
# @param [RDF::Queryable] queryable
|
24
|
+
# the graph or repository to write
|
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, options = {}, &block)
|
35
|
+
debug(options) {"Using"}
|
36
|
+
Dataset.new(*operands).execute(queryable, options.merge(depth: options[:depth].to_i + 1), &block)
|
37
|
+
end
|
38
|
+
end # Using
|
39
|
+
end # Operator
|
40
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
|
4
|
+
##
|
5
|
+
# The SPARQL UPDATE `with` operator.
|
6
|
+
#
|
7
|
+
# The WITH clause provides a convenience for when an operation primarily refers to a single graph.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# (with :g1
|
11
|
+
# (bgp (triple ?s ?p ?o))
|
12
|
+
# (insert ((triple ?s ?p "z"))))
|
13
|
+
#
|
14
|
+
# @see http://www.w3.org/TR/sparql11-update/#deleteInsert
|
15
|
+
class With < Operator
|
16
|
+
include SPARQL::Algebra::Update
|
17
|
+
|
18
|
+
NAME = :with
|
19
|
+
|
20
|
+
##
|
21
|
+
# Executes this upate on the given `writable` graph or repository.
|
22
|
+
#
|
23
|
+
# Effectively filters results by setting a default `__context__` variable so that it is used when binding to perform update operations on the appropriate triples.
|
24
|
+
#
|
25
|
+
# @param [RDF::Queryable] queryable
|
26
|
+
# the graph or repository to write
|
27
|
+
# @param [Hash{Symbol => Object}] options
|
28
|
+
# any additional keyword options
|
29
|
+
# @option options [Boolean] debug
|
30
|
+
# Query execution debugging
|
31
|
+
# @return [RDF::Queryable]
|
32
|
+
# Returns queryable.
|
33
|
+
# @raise [IOError]
|
34
|
+
# If `from` does not exist, unless the `silent` operator is present
|
35
|
+
# @see http://www.w3.org/TR/sparql11-update/
|
36
|
+
def execute(queryable, options = {})
|
37
|
+
debug(options) {"With: #{operand.to_sse}"}
|
38
|
+
# Bound variable
|
39
|
+
name = operands.shift
|
40
|
+
|
41
|
+
unless queryable.has_context?(name)
|
42
|
+
debug(options) {"=> default data source #{name}"}
|
43
|
+
load_opts = {debug: options.fetch(:debug, nil), base_uri: name}
|
44
|
+
debug(options) {"=> load #{name}"}
|
45
|
+
queryable.load(name.to_s, load_opts)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Set name for RDF::Graph descendants having no context to the name variable
|
49
|
+
descendants do |op|
|
50
|
+
case op
|
51
|
+
when RDF::Query, RDF::Query::Pattern
|
52
|
+
unless op.context
|
53
|
+
debug(options) {"set context on #{op.to_sse}"}
|
54
|
+
op.context = RDF::Query::Variable.new(:__context__, name)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
query = operands.shift
|
59
|
+
|
60
|
+
# Restrict query portion to this graph
|
61
|
+
queryable.query(query, options.merge(depth: options[:depth].to_i + 1)) do |solution|
|
62
|
+
debug(options) {"(solution)=>#{solution.inspect}"}
|
63
|
+
|
64
|
+
# Execute each operand with queryable and solution
|
65
|
+
operands.each do |op|
|
66
|
+
op.execute(queryable, solution, options.merge(depth: options[:depth].to_i + 1))
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end # With
|
71
|
+
end # Operator
|
72
|
+
end; end # SPARQL::Algebra
|