sparql 3.2.0 → 3.2.4
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 +59 -38
- data/VERSION +1 -1
- data/bin/sparql +2 -31
- data/lib/rack/sparql/conneg.rb +22 -1
- data/lib/sinatra/sparql/extensions.rb +1 -1
- data/lib/sinatra/sparql.rb +57 -12
- data/lib/sparql/algebra/expression.rb +63 -10
- data/lib/sparql/algebra/extensions.rb +39 -35
- data/lib/sparql/algebra/operator/abs.rb +1 -1
- data/lib/sparql/algebra/operator/adjust.rb +69 -0
- data/lib/sparql/algebra/operator/alt.rb +1 -1
- data/lib/sparql/algebra/operator/avg.rb +3 -1
- data/lib/sparql/algebra/operator/bgp.rb +9 -1
- data/lib/sparql/algebra/operator/clear.rb +13 -3
- data/lib/sparql/algebra/operator/construct.rb +1 -1
- data/lib/sparql/algebra/operator/count.rb +36 -6
- data/lib/sparql/algebra/operator/create.rb +5 -4
- data/lib/sparql/algebra/operator/dataset.rb +29 -11
- data/lib/sparql/algebra/operator/day.rb +2 -2
- data/lib/sparql/algebra/operator/delete.rb +3 -1
- data/lib/sparql/algebra/operator/delete_data.rb +1 -1
- data/lib/sparql/algebra/operator/delete_where.rb +1 -1
- data/lib/sparql/algebra/operator/distinct.rb +2 -2
- data/lib/sparql/algebra/operator/divide.rb +1 -1
- data/lib/sparql/algebra/operator/drop.rb +15 -6
- data/lib/sparql/algebra/operator/encode_for_uri.rb +2 -4
- data/lib/sparql/algebra/operator/exprlist.rb +3 -1
- data/lib/sparql/algebra/operator/extend.rb +73 -5
- data/lib/sparql/algebra/operator/filter.rb +6 -1
- data/lib/sparql/algebra/operator/function_call.rb +64 -0
- data/lib/sparql/algebra/operator/graph.rb +57 -7
- data/lib/sparql/algebra/operator/group.rb +105 -6
- data/lib/sparql/algebra/operator/group_concat.rb +25 -1
- data/lib/sparql/algebra/operator/hours.rb +2 -2
- data/lib/sparql/algebra/operator/if.rb +10 -10
- data/lib/sparql/algebra/operator/insert.rb +3 -1
- data/lib/sparql/algebra/operator/insert_data.rb +1 -1
- data/lib/sparql/algebra/operator/is_blank.rb +1 -2
- data/lib/sparql/algebra/operator/is_iri.rb +1 -2
- data/lib/sparql/algebra/operator/is_literal.rb +1 -2
- data/lib/sparql/algebra/operator/is_numeric.rb +1 -2
- data/lib/sparql/algebra/operator/join.rb +39 -5
- data/lib/sparql/algebra/operator/lcase.rb +2 -3
- data/lib/sparql/algebra/operator/left_join.rb +27 -9
- data/lib/sparql/algebra/operator/max.rb +3 -1
- data/lib/sparql/algebra/operator/min.rb +4 -2
- data/lib/sparql/algebra/operator/minus.rb +46 -6
- data/lib/sparql/algebra/operator/minutes.rb +2 -2
- data/lib/sparql/algebra/operator/modify.rb +21 -0
- data/lib/sparql/algebra/operator/month.rb +2 -2
- data/lib/sparql/algebra/operator/multiply.rb +1 -1
- data/lib/sparql/algebra/operator/notoneof.rb +12 -3
- data/lib/sparql/algebra/operator/order.rb +44 -0
- data/lib/sparql/algebra/operator/path_opt.rb +9 -65
- data/lib/sparql/algebra/operator/path_plus.rb +18 -10
- data/lib/sparql/algebra/operator/path_range.rb +178 -0
- data/lib/sparql/algebra/operator/path_star.rb +7 -4
- data/lib/sparql/algebra/operator/path_zero.rb +110 -0
- data/lib/sparql/algebra/operator/plus.rb +8 -6
- data/lib/sparql/algebra/operator/project.rb +64 -5
- data/lib/sparql/algebra/operator/reduced.rb +3 -3
- data/lib/sparql/algebra/operator/regex.rb +1 -1
- data/lib/sparql/algebra/operator/reverse.rb +12 -1
- data/lib/sparql/algebra/operator/sample.rb +3 -1
- data/lib/sparql/algebra/operator/seconds.rb +2 -2
- data/lib/sparql/algebra/operator/seq.rb +4 -4
- data/lib/sparql/algebra/operator/sequence.rb +14 -1
- data/lib/sparql/algebra/operator/service.rb +86 -0
- data/lib/sparql/algebra/operator/strlang.rb +1 -2
- data/lib/sparql/algebra/operator/subtract.rb +10 -6
- data/lib/sparql/algebra/operator/sum.rb +9 -7
- data/lib/sparql/algebra/operator/table.rb +50 -7
- data/lib/sparql/algebra/operator/timezone.rb +2 -2
- data/lib/sparql/algebra/operator/triple.rb +51 -0
- data/lib/sparql/algebra/operator/tz.rb +2 -2
- data/lib/sparql/algebra/operator/ucase.rb +1 -1
- data/lib/sparql/algebra/operator/update.rb +22 -1
- data/lib/sparql/algebra/operator/using.rb +18 -1
- data/lib/sparql/algebra/operator/with.rb +1 -1
- data/lib/sparql/algebra/operator/year.rb +2 -2
- data/lib/sparql/algebra/operator.rb +69 -22
- data/lib/sparql/algebra/query.rb +5 -3
- data/lib/sparql/algebra.rb +42 -6
- data/lib/sparql/grammar/meta.rb +1367 -267
- data/lib/sparql/grammar/parser11.rb +842 -331
- data/lib/sparql/grammar/terminals11.rb +2 -2
- data/lib/sparql/grammar.rb +6 -4
- data/lib/sparql/results.rb +3 -2
- data/lib/sparql/server.rb +93 -0
- data/lib/sparql.rb +8 -5
- metadata +49 -13
@@ -0,0 +1,86 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL Service operator.
|
5
|
+
#
|
6
|
+
# [59] ServiceGraphPattern ::= 'SERVICE' 'SILENT'? VarOrIri GroupGraphPattern
|
7
|
+
#
|
8
|
+
# @example SPARQL Grammar
|
9
|
+
# PREFIX : <http://example.org/>
|
10
|
+
#
|
11
|
+
# SELECT ?s ?o1 ?o2 {
|
12
|
+
# ?s ?p1 ?o1 .
|
13
|
+
# SERVICE <http://example.org/sparql> {
|
14
|
+
# ?s ?p2 ?o2
|
15
|
+
# }
|
16
|
+
# }
|
17
|
+
#
|
18
|
+
# @example SSE
|
19
|
+
# (prefix ((: <http://example.org/>))
|
20
|
+
# (project (?s ?o1 ?o2)
|
21
|
+
# (join
|
22
|
+
# (bgp (triple ?s ?p1 ?o1))
|
23
|
+
# (service :sparql
|
24
|
+
# (bgp (triple ?s ?p2 ?o2))))))
|
25
|
+
#
|
26
|
+
# @see https://www.w3.org/TR/sparql11-query/#QSynIRI
|
27
|
+
class Service < Operator
|
28
|
+
include Query
|
29
|
+
|
30
|
+
NAME = [:service]
|
31
|
+
|
32
|
+
##
|
33
|
+
# Executes this query on the given `queryable` graph or repository.
|
34
|
+
# Really a pass-through, as this is a syntactic object used for providing
|
35
|
+
# graph_name for URIs.
|
36
|
+
#
|
37
|
+
# @param [RDF::Queryable] queryable
|
38
|
+
# the graph or repository to query
|
39
|
+
# @param [Hash{Symbol => Object}] options
|
40
|
+
# any additional keyword options
|
41
|
+
# @yield [solution]
|
42
|
+
# each matching solution, statement or boolean
|
43
|
+
# @yieldparam [RDF::Statement, RDF::Query::Solution, Boolean] solution
|
44
|
+
# @yieldreturn [void] ignored
|
45
|
+
# @return [RDF::Query::Solutions]
|
46
|
+
# the resulting solution sequence
|
47
|
+
# @see https://www.w3.org/TR/sparql11-query/#sparqlAlgebra
|
48
|
+
def execute(queryable, **options, &block)
|
49
|
+
debug(options) {"Service"}
|
50
|
+
silent = operands.first == :silent
|
51
|
+
location, query = operands
|
52
|
+
query_sparql = query.to_sparql
|
53
|
+
debug(options) {"query: #{query_sparql}"}
|
54
|
+
raise NotImplementedError, "SERVICE operator not implemented"
|
55
|
+
end
|
56
|
+
|
57
|
+
##
|
58
|
+
# Returns an optimized version of this query.
|
59
|
+
#
|
60
|
+
# Replace with the query with URIs having their lexical shortcut removed
|
61
|
+
#
|
62
|
+
# @return [Prefix] a copy of `self`
|
63
|
+
# @see SPARQL::Algebra::Expression#optimize
|
64
|
+
def optimize(**options)
|
65
|
+
operands.last.optimize(**options)
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
#
|
70
|
+
# Returns a partial SPARQL grammar for this term.
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
def to_sparql(**options)
|
74
|
+
silent = operands.first == :silent
|
75
|
+
ops = silent ? operands[1..-1] : operands
|
76
|
+
location, query = ops
|
77
|
+
|
78
|
+
|
79
|
+
str = "SERVICE "
|
80
|
+
str << "SILENT " if silent
|
81
|
+
str << location.to_sparql(**options) + " {" + query.to_sparql(**options) + "}"
|
82
|
+
str
|
83
|
+
end
|
84
|
+
end # Service
|
85
|
+
end # Operator
|
86
|
+
end; end # SPARQL::Algebra
|
@@ -13,8 +13,7 @@ module SPARQL; module Algebra
|
|
13
13
|
# }
|
14
14
|
#
|
15
15
|
# @example SSE
|
16
|
-
# (prefix
|
17
|
-
# ((: <http://example.org/>) (xsd: <http://www.w3.org/2001/XMLSchema#>))
|
16
|
+
# (prefix ((: <http://example.org/>))
|
18
17
|
# (project (?s ?s2)
|
19
18
|
# (extend ((?s2 (strlang ?str "en-US")))
|
20
19
|
# (filter (langMatches (lang ?str) "en")
|
@@ -31,17 +31,21 @@ module SPARQL; module Algebra
|
|
31
31
|
##
|
32
32
|
# Returns the arithmetic difference of the operands.
|
33
33
|
#
|
34
|
-
# @param [RDF::Literal::Numeric] left
|
34
|
+
# @param [RDF::Literal::Numeric, RDF::Literal::Temporal] left
|
35
35
|
# a numeric literal
|
36
|
-
# @param [RDF::Literal::Numeric] right
|
36
|
+
# @param [RDF::Literal::Numeric, RDF::Literal::Temporal, RDF::Literal::Duration] right
|
37
37
|
# a numeric literal
|
38
|
-
# @return [RDF::Literal::Numeric]
|
39
|
-
# @raise [TypeError] if either operand is
|
38
|
+
# @return [RDF::Literal::Numeric, RDF::Literal::Temporal, RDF::Literal::Duration]
|
39
|
+
# @raise [TypeError] if either operand is neither a numeric nor a temporal literal
|
40
40
|
def apply(left, right, **options)
|
41
41
|
case
|
42
42
|
when left.is_a?(RDF::Literal::Numeric) && right.is_a?(RDF::Literal::Numeric)
|
43
43
|
left - right
|
44
|
-
|
44
|
+
when left.is_a?(RDF::Literal::Temporal) && right.is_a?(RDF::Literal::Temporal)
|
45
|
+
left - right
|
46
|
+
when left.is_a?(RDF::Literal::Temporal) && right.is_a?(RDF::Literal::Duration)
|
47
|
+
left - right
|
48
|
+
else raise TypeError, "expected two RDF::Literal::Numeric, Temporal operands, or a Temporal and a Duration, but got #{left.inspect} and #{right.inspect}"
|
45
49
|
end
|
46
50
|
end
|
47
51
|
|
@@ -51,7 +55,7 @@ module SPARQL; module Algebra
|
|
51
55
|
#
|
52
56
|
# @return [String]
|
53
57
|
def to_sparql(**options)
|
54
|
-
"#{operands.first.to_sparql(**options)} - #{operands.last.to_sparql(**options)}"
|
58
|
+
"(#{operands.first.to_sparql(**options)} - #{operands.last.to_sparql(**options)})"
|
55
59
|
end
|
56
60
|
end # Subtract
|
57
61
|
end # Operator
|
@@ -7,15 +7,15 @@ module SPARQL; module Algebra
|
|
7
7
|
#
|
8
8
|
# @example SPARQL Grammar
|
9
9
|
# PREFIX : <http://www.example.org/>
|
10
|
-
# SELECT (SUM(?
|
10
|
+
# SELECT (SUM(?o) AS ?sum)
|
11
11
|
# WHERE { ?s :dec ?o }
|
12
12
|
#
|
13
13
|
# @example SSE
|
14
|
-
#
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
14
|
+
# (prefix ((: <http://www.example.org/>))
|
15
|
+
# (project (?sum)
|
16
|
+
# (extend ((?sum ??.0))
|
17
|
+
# (group () ((??.0 (sum ?o)))
|
18
|
+
# (bgp (triple ?s :dec ?o))))))
|
19
19
|
#
|
20
20
|
# @see https://www.w3.org/TR/sparql11-query/#defn_aggSum
|
21
21
|
class Sum < Operator
|
@@ -47,7 +47,9 @@ module SPARQL; module Algebra
|
|
47
47
|
#
|
48
48
|
# @return [String]
|
49
49
|
def to_sparql(**options)
|
50
|
-
|
50
|
+
distinct = operands.first == :distinct
|
51
|
+
args = distinct ? operands[1..-1] : operands
|
52
|
+
"SUM(#{'DISTINCT ' if distinct}#{args.to_sparql(**options)})"
|
51
53
|
end
|
52
54
|
end # Sum
|
53
55
|
end # Operator
|
@@ -8,7 +8,7 @@ module SPARQL; module Algebra
|
|
8
8
|
#
|
9
9
|
# [28] ValuesClause ::= ( 'VALUES' DataBlock )?
|
10
10
|
#
|
11
|
-
# @example SPARQL Grammar
|
11
|
+
# @example SPARQL Grammar (ValuesClause)
|
12
12
|
# PREFIX dc: <http://purl.org/dc/elements/1.1/>
|
13
13
|
# PREFIX : <http://example.org/book/>
|
14
14
|
# PREFIX ns: <http://example.org/ns#>
|
@@ -18,7 +18,7 @@ module SPARQL; module Algebra
|
|
18
18
|
# }
|
19
19
|
# VALUES ?book { :book1 }
|
20
20
|
#
|
21
|
-
# @example SSE
|
21
|
+
# @example SSE (ValuesClause)
|
22
22
|
# (prefix ((dc: <http://purl.org/dc/elements/1.1/>)
|
23
23
|
# (: <http://example.org/book/>)
|
24
24
|
# (ns: <http://example.org/ns#>))
|
@@ -27,8 +27,38 @@ module SPARQL; module Algebra
|
|
27
27
|
# (bgp (triple ?book dc:title ?title) (triple ?book ns:price ?price))
|
28
28
|
# (table (vars ?book) (row (?book :book1)))) ))
|
29
29
|
#
|
30
|
+
# @example SPARQL Grammar (empty query no values)
|
31
|
+
# SELECT * { } VALUES () { }
|
32
|
+
#
|
33
|
+
# @example SSE (empty query no values)
|
34
|
+
# (join (bgp) (table empty))
|
35
|
+
#
|
36
|
+
# [61] InlineData ::= 'VALUES' DataBlock
|
37
|
+
#
|
38
|
+
# @example SPARQL Grammar (InlineData)
|
39
|
+
# PREFIX dc: <http://purl.org/dc/elements/1.1/>
|
40
|
+
# PREFIX : <http://example.org/book/>
|
41
|
+
# PREFIX ns: <http://example.org/ns#>
|
42
|
+
#
|
43
|
+
# SELECT ?book ?title ?price
|
44
|
+
# {
|
45
|
+
# VALUES ?book { :book1 }
|
46
|
+
# ?book dc:title ?title ;
|
47
|
+
# ns:price ?price .
|
48
|
+
# }
|
49
|
+
#
|
50
|
+
# @example SSE (InlineData)
|
51
|
+
# (prefix ((dc: <http://purl.org/dc/elements/1.1/>)
|
52
|
+
# (: <http://example.org/book/>)
|
53
|
+
# (ns: <http://example.org/ns#>))
|
54
|
+
# (project (?book ?title ?price)
|
55
|
+
# (join
|
56
|
+
# (table (vars ?book) (row (?book :book1)))
|
57
|
+
# (bgp (triple ?book dc:title ?title) (triple ?book ns:price ?price))) ))
|
58
|
+
#
|
30
59
|
# @example empty table
|
31
60
|
# (table unit)
|
61
|
+
#
|
32
62
|
# @see https://www.w3.org/TR/2013/REC-sparql11-query-20130321/#inline-data
|
33
63
|
class Table < Operator
|
34
64
|
include Query
|
@@ -59,30 +89,43 @@ module SPARQL; module Algebra
|
|
59
89
|
end
|
60
90
|
@solutions << RDF::Query::Solution.new(bindings)
|
61
91
|
end
|
92
|
+
@solutions.variable_names = self.variables.keys
|
62
93
|
@solutions.each(&block) if block_given?
|
63
94
|
@solutions
|
64
95
|
end
|
96
|
+
|
97
|
+
##
|
98
|
+
# In-scope variables for a table are the variables operand
|
99
|
+
#
|
100
|
+
# @return [Hash{Symbol => RDF::Query::Variable}]
|
101
|
+
def variables
|
102
|
+
in_scope = operands.first.is_a?(Array) ? operands.first[1..-1] : []
|
103
|
+
in_scope.inject({}) {|memo, v| memo.merge(v.variables)}
|
104
|
+
end
|
65
105
|
|
66
106
|
##
|
67
107
|
#
|
68
108
|
# Returns a partial SPARQL grammar for this operator.
|
69
109
|
#
|
110
|
+
# @param [Boolean] top_level (true)
|
111
|
+
# Treat this as a top-level, generating SELECT ... WHERE {}
|
70
112
|
# @return [String]
|
71
|
-
def to_sparql(**options)
|
72
|
-
str = "VALUES (#{operands.first[1..-1].map { |e| e.to_sparql(**options) }.join(' ')}) {\n"
|
113
|
+
def to_sparql(top_level: true, **options)
|
114
|
+
str = "VALUES (#{Array(operands.first)[1..-1].map { |e| e.to_sparql(**options) }.join(' ')}) {\n"
|
73
115
|
operands[1..-1].each do |row|
|
74
116
|
line = '('
|
75
117
|
row[1..-1].each do |col|
|
76
|
-
|
118
|
+
v = col[1].to_sparql(**options)
|
119
|
+
line << v + ' '
|
77
120
|
end
|
78
|
-
line = line.
|
121
|
+
line = line.chomp(' ')
|
79
122
|
line << ")\n"
|
80
123
|
|
81
124
|
str << line
|
82
125
|
end
|
83
126
|
|
84
127
|
str << "}\n"
|
85
|
-
str
|
128
|
+
top_level ? Operator.to_sparql(str, **options) : str
|
86
129
|
end
|
87
130
|
end # Table
|
88
131
|
end # Operator
|
@@ -33,10 +33,10 @@ module SPARQL; module Algebra
|
|
33
33
|
#
|
34
34
|
# @param [RDF::Literal] operand
|
35
35
|
# the operand
|
36
|
-
# @return [RDF::Literal]
|
36
|
+
# @return [RDF::Literal::Temporal]
|
37
37
|
# @raise [TypeError] if the operand is not a simple literal
|
38
38
|
def apply(operand, **options)
|
39
|
-
raise TypeError, "expected an RDF::Literal::
|
39
|
+
raise TypeError, "expected an RDF::Literal::Temporal, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::Temporal)
|
40
40
|
raise TypeError, "literal has no timezone" unless res = operand.timezone
|
41
41
|
res
|
42
42
|
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL `triple` operator.
|
5
|
+
#
|
6
|
+
# If the 3-tuple (term1, term2, term3) is an RDF-star triple, the function returns this triple. If the 3-tuple is not an RDF-star triple, then the function raises an error.
|
7
|
+
#
|
8
|
+
# [121] BuiltInCall ::= ... | 'TRIPLE' '(' Expression ',' Expression ',' Expression ')'
|
9
|
+
#
|
10
|
+
# @example SPARQL Grammar
|
11
|
+
# PREFIX : <http://example.com/ns#>
|
12
|
+
# SELECT * {
|
13
|
+
# ?s ?p ?o .
|
14
|
+
# BIND(TRIPLE(?s, ?p, ?o) AS ?t1)
|
15
|
+
# }
|
16
|
+
#
|
17
|
+
# @example SSE
|
18
|
+
# (prefix ((: <http://example.com/ns#>))
|
19
|
+
# (extend ((?t1 (triple ?s ?p ?o)))
|
20
|
+
# (bgp (triple ?s ?p ?o))))
|
21
|
+
#
|
22
|
+
# @note This operator overlaps with RDF::Query::Pattern as used as an operand to a BGP.
|
23
|
+
# @see https://w3c.github.io/rdf-star/rdf-star-cg-spec.html#triple
|
24
|
+
class Triple < Operator::Ternary
|
25
|
+
include Evaluatable
|
26
|
+
|
27
|
+
NAME = :triple
|
28
|
+
|
29
|
+
##
|
30
|
+
# @param [RDF::Term] subject
|
31
|
+
# @param [RDF::Term] predicate
|
32
|
+
# @param [RDF::Term] object
|
33
|
+
# @return [RDF::URI]
|
34
|
+
# @raise [TypeError] if the operand is not a simple literal
|
35
|
+
def apply(subject, predicate, object, **options)
|
36
|
+
triple = RDF::Statement(subject, predicate, object)
|
37
|
+
raise TypeError, "valid components, but got #{triple.inspect}" unless triple.valid?
|
38
|
+
triple
|
39
|
+
end
|
40
|
+
|
41
|
+
##
|
42
|
+
#
|
43
|
+
# Returns a partial SPARQL grammar for this operator.
|
44
|
+
#
|
45
|
+
# @return [String]
|
46
|
+
def to_sparql(**options)
|
47
|
+
"TRIPLE(#{operands.to_sparql(delimiter: ', ', **options)})"
|
48
|
+
end
|
49
|
+
end # Triple
|
50
|
+
end # Operator
|
51
|
+
end; end # SPARQL::Algebra
|
@@ -29,12 +29,12 @@ module SPARQL; module Algebra
|
|
29
29
|
##
|
30
30
|
# Returns the timezone part of arg as a simple literal. Returns the empty string if there is no timezone.
|
31
31
|
#
|
32
|
-
# @param [RDF::Literal] operand
|
32
|
+
# @param [RDF::Literal::Temporal] operand
|
33
33
|
# the operand
|
34
34
|
# @return [RDF::Literal]
|
35
35
|
# @raise [TypeError] if the operand is not a simple literal
|
36
36
|
def apply(operand, **options)
|
37
|
-
raise TypeError, "expected an RDF::Literal::
|
37
|
+
raise TypeError, "expected an RDF::Literal::Temporal, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::Temporal)
|
38
38
|
operand.tz
|
39
39
|
end
|
40
40
|
##
|
@@ -21,6 +21,27 @@ module SPARQL; module Algebra
|
|
21
21
|
# (delete ((triple ?a foaf:knows ?b)))
|
22
22
|
# (insert ((triple ?b foaf:knows ?a)))) ))
|
23
23
|
#
|
24
|
+
# @example SPARQL Grammar (update multiple)
|
25
|
+
# PREFIX : <http://example.org/>
|
26
|
+
# PREFIX foaf: <http://xmlns.com/foaf/0.1/>
|
27
|
+
#
|
28
|
+
# DELETE { ?a foaf:knows ?b . }
|
29
|
+
# WHERE { ?a foaf:knows ?b . }
|
30
|
+
# ;
|
31
|
+
# INSERT { ?b foaf:knows ?a . }
|
32
|
+
# WHERE { ?a foaf:knows ?b .}
|
33
|
+
#
|
34
|
+
# @example SSE (update multiple)
|
35
|
+
# (prefix ((: <http://example.org/>)
|
36
|
+
# (foaf: <http://xmlns.com/foaf/0.1/>))
|
37
|
+
# (update
|
38
|
+
# (modify
|
39
|
+
# (bgp (triple ?a foaf:knows ?b))
|
40
|
+
# (delete ((triple ?a foaf:knows ?b))))
|
41
|
+
# (modify
|
42
|
+
# (bgp (triple ?a foaf:knows ?b))
|
43
|
+
# (insert ((triple ?b foaf:knows ?a))))))
|
44
|
+
#
|
24
45
|
# @see https://www.w3.org/TR/sparql11-update/#graphUpdate
|
25
46
|
class Update < Operator
|
26
47
|
include SPARQL::Algebra::Update
|
@@ -58,7 +79,7 @@ module SPARQL; module Algebra
|
|
58
79
|
#
|
59
80
|
# @return [String]
|
60
81
|
def to_sparql(**options)
|
61
|
-
str = operands.map { |e| e.to_sparql(**options) }.join("
|
82
|
+
str = operands.map { |e| e.to_sparql(**options) }.join(";\n")
|
62
83
|
end
|
63
84
|
end # Update
|
64
85
|
end # Operator
|
@@ -28,6 +28,21 @@ module SPARQL; module Algebra
|
|
28
28
|
# (bgp (triple :a foaf:knows ?s) (triple ?s ?p ?o)))
|
29
29
|
# (delete ((triple ?s ?p ?o)))) ))
|
30
30
|
#
|
31
|
+
# @example SPARQL Grammar (multiple clauses)
|
32
|
+
# PREFIX : <http://example.org/>
|
33
|
+
#
|
34
|
+
# INSERT { ?s ?p "q" }
|
35
|
+
# USING :g1
|
36
|
+
# USING :g2
|
37
|
+
# WHERE { ?s ?p ?o }
|
38
|
+
#
|
39
|
+
# @example SSE (multiple clauses)
|
40
|
+
# (prefix ((: <http://example.org/>))
|
41
|
+
# (update
|
42
|
+
# (modify
|
43
|
+
# (using (:g1 :g2) (bgp (triple ?s ?p ?o)))
|
44
|
+
# (insert ((triple ?s ?p "q"))))))
|
45
|
+
#
|
31
46
|
# @see https://www.w3.org/TR/sparql11-update/#add
|
32
47
|
class Using < Operator
|
33
48
|
include SPARQL::Algebra::Query
|
@@ -61,7 +76,9 @@ module SPARQL; module Algebra
|
|
61
76
|
#
|
62
77
|
# @return [String]
|
63
78
|
def to_sparql(**options)
|
64
|
-
str = "
|
79
|
+
str = "\n" + operands.first.map do |op|
|
80
|
+
"USING #{op.to_sparql(**options)}\n"
|
81
|
+
end.join("")
|
65
82
|
content = operands.last.to_sparql(top_level: false, **options)
|
66
83
|
str << Operator.to_sparql(content, project: nil, **options)
|
67
84
|
end
|
@@ -31,10 +31,10 @@ module SPARQL; module Algebra
|
|
31
31
|
#
|
32
32
|
# @param [RDF::Literal] operand
|
33
33
|
# the operand
|
34
|
-
# @return [RDF::Literal]
|
34
|
+
# @return [RDF::Literal::Temporal]
|
35
35
|
# @raise [TypeError] if the operand is not a simple literal
|
36
36
|
def apply(operand, **options)
|
37
|
-
raise TypeError, "expected an RDF::Literal::
|
37
|
+
raise TypeError, "expected an RDF::Literal::Temporal, but got #{operand.inspect}" unless operand.is_a?(RDF::Literal::Temporal)
|
38
38
|
RDF::Literal(operand.object.year)
|
39
39
|
end
|
40
40
|
|