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
@@ -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
|