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.
Files changed (76) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +36 -32
  3. data/VERSION +1 -1
  4. data/bin/sparql +8 -6
  5. data/lib/sparql.rb +4 -2
  6. data/lib/sparql/algebra.rb +74 -4
  7. data/lib/sparql/algebra/aggregate.rb +1 -1
  8. data/lib/sparql/algebra/evaluatable.rb +1 -1
  9. data/lib/sparql/algebra/expression.rb +24 -16
  10. data/lib/sparql/algebra/extensions.rb +37 -9
  11. data/lib/sparql/algebra/operator.rb +75 -12
  12. data/lib/sparql/algebra/operator/add.rb +41 -19
  13. data/lib/sparql/algebra/operator/and.rb +2 -2
  14. data/lib/sparql/algebra/operator/asc.rb +1 -1
  15. data/lib/sparql/algebra/operator/ask.rb +1 -1
  16. data/lib/sparql/algebra/operator/base.rb +1 -1
  17. data/lib/sparql/algebra/operator/bgp.rb +1 -1
  18. data/lib/sparql/algebra/operator/bnode.rb +1 -1
  19. data/lib/sparql/algebra/operator/clear.rb +63 -0
  20. data/lib/sparql/algebra/operator/coalesce.rb +1 -1
  21. data/lib/sparql/algebra/operator/concat.rb +3 -3
  22. data/lib/sparql/algebra/operator/construct.rb +2 -2
  23. data/lib/sparql/algebra/operator/copy.rb +64 -0
  24. data/lib/sparql/algebra/operator/create.rb +49 -0
  25. data/lib/sparql/algebra/operator/dataset.rb +6 -31
  26. data/lib/sparql/algebra/operator/delete.rb +55 -0
  27. data/lib/sparql/algebra/operator/delete_data.rb +41 -0
  28. data/lib/sparql/algebra/operator/delete_where.rb +57 -0
  29. data/lib/sparql/algebra/operator/distinct.rb +1 -1
  30. data/lib/sparql/algebra/operator/drop.rb +66 -0
  31. data/lib/sparql/algebra/operator/exists.rb +2 -2
  32. data/lib/sparql/algebra/operator/exprlist.rb +1 -1
  33. data/lib/sparql/algebra/operator/extend.rb +3 -3
  34. data/lib/sparql/algebra/operator/filter.rb +2 -2
  35. data/lib/sparql/algebra/operator/graph.rb +39 -5
  36. data/lib/sparql/algebra/operator/group.rb +5 -5
  37. data/lib/sparql/algebra/operator/group_concat.rb +1 -1
  38. data/lib/sparql/algebra/operator/if.rb +3 -3
  39. data/lib/sparql/algebra/operator/in.rb +1 -1
  40. data/lib/sparql/algebra/operator/insert.rb +54 -0
  41. data/lib/sparql/algebra/operator/insert_data.rb +41 -0
  42. data/lib/sparql/algebra/operator/join.rb +2 -2
  43. data/lib/sparql/algebra/operator/lcase.rb +1 -1
  44. data/lib/sparql/algebra/operator/left_join.rb +2 -2
  45. data/lib/sparql/algebra/operator/load.rb +48 -0
  46. data/lib/sparql/algebra/operator/minus.rb +2 -2
  47. data/lib/sparql/algebra/operator/modify.rb +53 -0
  48. data/lib/sparql/algebra/operator/move.rb +67 -0
  49. data/lib/sparql/algebra/operator/notexists.rb +1 -1
  50. data/lib/sparql/algebra/operator/notin.rb +2 -2
  51. data/lib/sparql/algebra/operator/or.rb +2 -2
  52. data/lib/sparql/algebra/operator/order.rb +3 -3
  53. data/lib/sparql/algebra/operator/plus.rb +14 -8
  54. data/lib/sparql/algebra/operator/prefix.rb +1 -1
  55. data/lib/sparql/algebra/operator/project.rb +1 -1
  56. data/lib/sparql/algebra/operator/reduced.rb +1 -1
  57. data/lib/sparql/algebra/operator/replace.rb +1 -1
  58. data/lib/sparql/algebra/operator/slice.rb +1 -1
  59. data/lib/sparql/algebra/operator/strafter.rb +1 -1
  60. data/lib/sparql/algebra/operator/strbefore.rb +2 -2
  61. data/lib/sparql/algebra/operator/strdt.rb +1 -1
  62. data/lib/sparql/algebra/operator/strlang.rb +1 -1
  63. data/lib/sparql/algebra/operator/substr.rb +2 -2
  64. data/lib/sparql/algebra/operator/ucase.rb +1 -1
  65. data/lib/sparql/algebra/operator/union.rb +1 -1
  66. data/lib/sparql/algebra/operator/update.rb +44 -0
  67. data/lib/sparql/algebra/operator/using.rb +40 -0
  68. data/lib/sparql/algebra/operator/with.rb +72 -0
  69. data/lib/sparql/algebra/update.rb +56 -0
  70. data/lib/sparql/extensions.rb +8 -8
  71. data/lib/sparql/grammar.rb +31 -8
  72. data/lib/sparql/grammar/meta.rb +3758 -3273
  73. data/lib/sparql/grammar/parser11.rb +240 -46
  74. data/lib/sparql/grammar/terminals11.rb +5 -5
  75. data/lib/sparql/results.rb +26 -26
  76. 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(:solutions => solutions)).empty?
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(:depth => options[:depth].to_i + 1))
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(:depth => options[:depth].to_i + 1))
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(:depth => options[:depth].to_i + 1))).true?
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(:depth => options[:depth].to_i + 1))).true?
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(:depth => options[:depth].to_i + 1)).order do |a, b|
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(: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
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 operand with its sign unchanged.
18
+ # Returns the arithmetic sum of the operands, unless there is no `right`.
18
19
  #
19
- # @param [RDF::Literal::Numeric] term
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 the operand is not a numeric literal
23
- def apply(term)
24
- case term
25
- when RDF::Literal::Numeric then term
26
- else raise TypeError, "expected an RDF::Literal::Numeric, but got #{term.inspect}"
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(:depth => options[:depth].to_i + 1), &block)
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(:depth => options[:depth].to_i + 1))
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(:depth => options[:depth].to_i + 1)).reduced
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), :datatype => text.datatype, :language => text.language)
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(:depth => options[:depth].to_i + 1))
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, :datatype => left.datatype, :language => left.language)
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("", :language => left.language, :datatype => left.datatype)
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, :language => left.language, :datatype => left.datatype)
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, :datatype => datatypeIRI)
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, :language => langTag.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], :datatype => source.datatype, :language => source.language)
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], :datatype => source.datatype, :language => source.language)
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, :datatype => operand.datatype, :language => operand.language)
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(:depth => options[:depth].to_i + 1))
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