sparql 1.0.6 → 1.0.7
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +11 -4
- data/VERSION +1 -1
- data/lib/sparql/algebra/extensions.rb +36 -0
- data/lib/sparql/algebra/operator.rb +197 -87
- data/lib/sparql/algebra/operator/abs.rb +31 -0
- data/lib/sparql/algebra/operator/base.rb +1 -0
- data/lib/sparql/algebra/operator/bnode.rb +88 -0
- data/lib/sparql/algebra/operator/bound.rb +2 -1
- data/lib/sparql/algebra/operator/ceil.rb +31 -0
- data/lib/sparql/algebra/operator/coalesce.rb +65 -0
- data/lib/sparql/algebra/operator/concat.rb +49 -0
- data/lib/sparql/algebra/operator/contains.rb +44 -0
- data/lib/sparql/algebra/operator/dataset.rb +11 -48
- data/lib/sparql/algebra/operator/datatype.rb +4 -2
- data/lib/sparql/algebra/operator/day.rb +31 -0
- data/lib/sparql/algebra/operator/encode_for_uri.rb +38 -0
- data/lib/sparql/algebra/operator/extend.rb +31 -2
- data/lib/sparql/algebra/operator/floor.rb +33 -0
- data/lib/sparql/algebra/operator/hours.rb +31 -0
- data/lib/sparql/algebra/operator/if.rb +55 -0
- data/lib/sparql/algebra/operator/in.rb +68 -0
- data/lib/sparql/algebra/operator/iri.rb +40 -0
- data/lib/sparql/algebra/operator/is_numeric.rb +41 -0
- data/lib/sparql/algebra/operator/lang_matches.rb +2 -2
- data/lib/sparql/algebra/operator/lcase.rb +31 -0
- data/lib/sparql/algebra/operator/md5.rb +34 -0
- data/lib/sparql/algebra/operator/minutes.rb +31 -0
- data/lib/sparql/algebra/operator/month.rb +31 -0
- data/lib/sparql/algebra/operator/not.rb +2 -2
- data/lib/sparql/algebra/operator/notin.rb +70 -0
- data/lib/sparql/algebra/operator/now.rb +29 -0
- data/lib/sparql/algebra/operator/order.rb +9 -13
- data/lib/sparql/algebra/operator/rand.rb +24 -0
- data/lib/sparql/algebra/operator/replace.rb +81 -0
- data/lib/sparql/algebra/operator/round.rb +31 -0
- data/lib/sparql/algebra/operator/seconds.rb +31 -0
- data/lib/sparql/algebra/operator/sha1.rb +34 -0
- data/lib/sparql/algebra/operator/sha256.rb +34 -0
- data/lib/sparql/algebra/operator/sha384.rb +34 -0
- data/lib/sparql/algebra/operator/sha512.rb +34 -0
- data/lib/sparql/algebra/operator/strafter.rb +57 -0
- data/lib/sparql/algebra/operator/strbefore.rb +59 -0
- data/lib/sparql/algebra/operator/strdt.rb +33 -0
- data/lib/sparql/algebra/operator/strends.rb +46 -0
- data/lib/sparql/algebra/operator/strlang.rb +34 -0
- data/lib/sparql/algebra/operator/strlen.rb +34 -0
- data/lib/sparql/algebra/operator/strstarts.rb +46 -0
- data/lib/sparql/algebra/operator/struuid.rb +32 -0
- data/lib/sparql/algebra/operator/substr.rb +80 -0
- data/lib/sparql/algebra/operator/timezone.rb +34 -0
- data/lib/sparql/algebra/operator/tz.rb +31 -0
- data/lib/sparql/algebra/operator/ucase.rb +31 -0
- data/lib/sparql/algebra/operator/uuid.rb +32 -0
- data/lib/sparql/algebra/operator/year.rb +31 -0
- data/lib/sparql/grammar/parser11.rb +128 -70
- data/lib/sparql/grammar/terminals11.rb +4 -5
- metadata +62 -7
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module SPARQL; module Algebra
|
4
|
+
class Operator
|
5
|
+
##
|
6
|
+
# The SPARQL logical `sha1` operator.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# (prefix ((: <http://example.org/>))
|
10
|
+
# (project (?hash)
|
11
|
+
# (extend ((?hash (sha384 ?l)))
|
12
|
+
# (bgp (triple :s1 :str ?l)))))
|
13
|
+
#
|
14
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-sha384
|
15
|
+
class SHA384 < Operator::Unary
|
16
|
+
include Evaluatable
|
17
|
+
|
18
|
+
NAME = :sha384
|
19
|
+
|
20
|
+
##
|
21
|
+
# Returns the SHA384 checksum, as a hex digit string, calculated on the UTF-8 representation of the simple literal or lexical form of the xsd:string. Hex digits should be in lower case.
|
22
|
+
#
|
23
|
+
# @param [RDF::Literal] operand
|
24
|
+
# the operand
|
25
|
+
# @return [RDF::Literal]
|
26
|
+
# @raise [TypeError] if the operand is not a simple literal
|
27
|
+
def apply(operand)
|
28
|
+
raise TypeError, "expected an RDF::Literal, but got #{operand.inspect}" unless operand.literal?
|
29
|
+
raise TypeError, "expected simple literal or xsd:string, but got #{operand.inspect}" unless (operand.datatype || RDF::XSD.string) == RDF::XSD.string
|
30
|
+
RDF::Literal(Digest::SHA384.new.hexdigest(operand.to_s))
|
31
|
+
end
|
32
|
+
end # SHA384
|
33
|
+
end # Operator
|
34
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'digest'
|
2
|
+
|
3
|
+
module SPARQL; module Algebra
|
4
|
+
class Operator
|
5
|
+
##
|
6
|
+
# The SPARQL logical `sha512` operator.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# (prefix ((: <http://example.org/>))
|
10
|
+
# (project (?hash)
|
11
|
+
# (extend ((?hash (sha512 ?l)))
|
12
|
+
# (bgp (triple :s1 :str ?l)))))
|
13
|
+
#
|
14
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-sha512
|
15
|
+
class SHA512 < Operator::Unary
|
16
|
+
include Evaluatable
|
17
|
+
|
18
|
+
NAME = :sha512
|
19
|
+
|
20
|
+
##
|
21
|
+
# Returns the SHA512 checksum, as a hex digit string, calculated on the UTF-8 representation of the simple literal or lexical form of the xsd:string. Hex digits should be in lower case.
|
22
|
+
#
|
23
|
+
# @param [RDF::Literal] operand
|
24
|
+
# the operand
|
25
|
+
# @return [RDF::Literal]
|
26
|
+
# @raise [TypeError] if the operand is not a simple literal
|
27
|
+
def apply(operand)
|
28
|
+
raise TypeError, "expected an RDF::Literal, but got #{operand.inspect}" unless operand.literal?
|
29
|
+
raise TypeError, "expected simple literal or xsd:string, but got #{operand.inspect}" unless (operand.datatype || RDF::XSD.string) == RDF::XSD.string
|
30
|
+
RDF::Literal(Digest::SHA512.new.hexdigest(operand.to_s))
|
31
|
+
end
|
32
|
+
end # SHA512
|
33
|
+
end # Operator
|
34
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# A SPARQL `strafter` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (strafter ?x ?y)
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-strafter
|
10
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-substring-after
|
11
|
+
class StrAfter < Operator::Binary
|
12
|
+
include Evaluatable
|
13
|
+
|
14
|
+
NAME = :strafter
|
15
|
+
|
16
|
+
##
|
17
|
+
# The STRAFTER function corresponds to the XPath fn:substring-after function. The arguments must be argument compatible otherwise an error is raised.
|
18
|
+
#
|
19
|
+
# For compatible arguments, if the lexical part of the second argument occurs as a substring of the lexical part of the first argument, the function returns a literal of the same kind as the first argument arg1 (simple literal, plain literal same language tag, xsd:string). The lexical form of the result is the substring of the lexcial form of arg1 that follows the first occurrence of the lexical form of arg2. 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 the lexical form of arg1.
|
20
|
+
#
|
21
|
+
# If there is no such occurrence, an empty simple literal is returned.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# strafter("abc","b") #=> "c"
|
25
|
+
# strafter("abc"@en,"ab") #=> "c"@en
|
26
|
+
# strafter("abc"@en,"b"@cy) #=> error
|
27
|
+
# strafter("abc"^^xsd:string,"") #=> "abc"^^xsd:string
|
28
|
+
# strafter("abc","xyz") #=> ""
|
29
|
+
# strafter("abc"@en, "z"@en) #=> ""
|
30
|
+
# strafter("abc"@en, "z") #=> ""
|
31
|
+
# strafter("abc"@en, ""@en) #=> "abc"@en
|
32
|
+
# strafter("abc"@en, "") #=> "abc"@en
|
33
|
+
#
|
34
|
+
# @param [RDF::Literal] left
|
35
|
+
# a literal
|
36
|
+
# @param [RDF::Literal] right
|
37
|
+
# a literal
|
38
|
+
# @return [RDF::Literal]
|
39
|
+
# @raise [TypeError] if operands are not compatible
|
40
|
+
def apply(left, right)
|
41
|
+
case
|
42
|
+
when !left.compatible?(right)
|
43
|
+
raise TypeError, "expected two RDF::Literal operands, but got #{left.inspect} and #{right.inspect}"
|
44
|
+
when right.to_s.empty?
|
45
|
+
# 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 the lexical form of arg1.
|
46
|
+
left
|
47
|
+
when !left.to_s.include?(right.to_s)
|
48
|
+
# 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.
|
49
|
+
RDF::Literal("")
|
50
|
+
else
|
51
|
+
parts = left.to_s.split(right.to_s)
|
52
|
+
RDF::Literal(parts.last, :datatype => left.datatype, :language => left.language)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end # StrAfter
|
56
|
+
end # Operator
|
57
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# A SPARQL `strbefore` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (strbefore ?x ?y)
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-strbefore
|
10
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-substring-before
|
11
|
+
class StrBefore < Operator::Binary
|
12
|
+
include Evaluatable
|
13
|
+
|
14
|
+
NAME = :strbefore
|
15
|
+
|
16
|
+
##
|
17
|
+
# The STRBEFORE function corresponds to the XPath fn:substring-before function. The arguments must be argument compatible otherwise an error is raised.
|
18
|
+
#
|
19
|
+
# For compatible arguments, if the lexical part of the second argument occurs as a substring of the lexical part of the first argument, the function returns a literal of the same kind as the first argument arg1 (simple literal, plain literal same language tag, xsd:string). The lexical form of the result is the substring of the lexical form of arg1 that precedes the first occurrence of the lexical form of arg2. 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 the empty string.
|
20
|
+
#
|
21
|
+
# If there is no such occurrence, an empty simple literal is returned.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# strbefore("abc","b") #=> "a"
|
25
|
+
# strbefore("abc"@en,"bc") #=> "a"@en
|
26
|
+
# strbefore("abc"@en,"b"@cy) #=> error
|
27
|
+
# strbefore("abc"^^xsd:string,"") #=> ""^^xsd:string
|
28
|
+
# strbefore("abc","xyz") #=> ""
|
29
|
+
# strbefore("abc"@en, "z"@en) #=> ""
|
30
|
+
# strbefore("abc"@en, "z") #=> ""
|
31
|
+
# strbefore("abc"@en, ""@en) #=> ""@en
|
32
|
+
# strbefore("abc"@en, "") #=> ""@en
|
33
|
+
#
|
34
|
+
# @param [RDF::Literal] left
|
35
|
+
# a literal
|
36
|
+
# @param [RDF::Literal] right
|
37
|
+
# a literal
|
38
|
+
# @return [RDF::Literal]
|
39
|
+
# @raise [TypeError] if operands are not compatible
|
40
|
+
def apply(left, right)
|
41
|
+
case
|
42
|
+
when !left.plain? || !right.plain?
|
43
|
+
raise TypeError, "expected two RDF::Literal operands, but got #{left.inspect} and #{right.inspect}"
|
44
|
+
when !left.compatible?(right)
|
45
|
+
raise TypeError, "expected two RDF::Literal operands, but got #{left.inspect} and #{right.inspect}"
|
46
|
+
when right.to_s.empty?
|
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)
|
49
|
+
when !left.to_s.include?(right.to_s)
|
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
|
+
RDF::Literal("")
|
52
|
+
else
|
53
|
+
parts = left.to_s.split(right.to_s)
|
54
|
+
RDF::Literal(parts.first, :language => left.language, :datatype => left.datatype)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end # StrBefore
|
58
|
+
end # Operator
|
59
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL `strdt` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (project (?s ?str1)
|
8
|
+
# (extend ((?str1 (strdt ?str xsd:string)))
|
9
|
+
# (filter (langMatches (lang ?str) "en")
|
10
|
+
# (bgp (triple ?s :str ?str))))))
|
11
|
+
#
|
12
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-strdt
|
13
|
+
class StrDT < Operator::Binary
|
14
|
+
include Evaluatable
|
15
|
+
|
16
|
+
NAME = :strdt
|
17
|
+
|
18
|
+
##
|
19
|
+
# Constructs a literal with lexical form and type as specified by the arguments.
|
20
|
+
#
|
21
|
+
# @param [RDF::Literal] value
|
22
|
+
# a literal
|
23
|
+
# @param [RDF::URI] datatypeIRI
|
24
|
+
# datatype
|
25
|
+
# @return [RDF::Literal] a datatyped literal
|
26
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-strdt
|
27
|
+
def apply(value, datatypeIRI)
|
28
|
+
raise TypeError, "Literal #{value.inspect} is not simple" unless value.simple?
|
29
|
+
RDF::Literal.new(value.to_s, :datatype => datatypeIRI)
|
30
|
+
end
|
31
|
+
end # StrDT
|
32
|
+
end # Operator
|
33
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# A SPARQL `contains` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (strends ?x ?y)
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-strends
|
10
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-ends-with
|
11
|
+
class StrEnds < Operator::Binary
|
12
|
+
include Evaluatable
|
13
|
+
|
14
|
+
NAME = :strends
|
15
|
+
|
16
|
+
##
|
17
|
+
# The STRENDS function corresponds to the XPath fn:ends-with function. The arguments must be argument compatible otherwise an error is raised.
|
18
|
+
#
|
19
|
+
# For such input pairs, the function returns true if the lexical form of arg1 ends with the lexical form of arg2, otherwise it returns false.
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# strEnds("foobar", "bar") #=> true
|
23
|
+
# strEnds("foobar"@en, "bar"@en) #=> true
|
24
|
+
# strEnds("foobar"^^xsd:string, "bar"^^xsd:string) #=> true
|
25
|
+
# strEnds("foobar"^^xsd:string, "bar") #=> true
|
26
|
+
# strEnds("foobar", "bar"^^xsd:string) #=> true
|
27
|
+
# strEnds("foobar"@en, "bar") #=> true
|
28
|
+
# strEnds("foobar"@en, "bar"^^xsd:string) #=> true
|
29
|
+
#
|
30
|
+
# @param [RDF::Literal] left
|
31
|
+
# a literal
|
32
|
+
# @param [RDF::Literal] right
|
33
|
+
# a literal
|
34
|
+
# @return [RDF::Literal::Boolean]
|
35
|
+
# @raise [TypeError] if operands are not compatible
|
36
|
+
def apply(left, right)
|
37
|
+
case
|
38
|
+
when !left.compatible?(right)
|
39
|
+
raise TypeError, "expected two RDF::Literal operands, but got #{left.inspect} and #{right.inspect}"
|
40
|
+
when left.to_s.end_with?(right.to_s) then RDF::Literal::TRUE
|
41
|
+
else RDF::Literal::FALSE
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end # StrEnds
|
45
|
+
end # Operator
|
46
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL `strlang` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (prefix ((: <http://example.org/>))
|
8
|
+
# (project (?s ?s2)
|
9
|
+
# (extend ((?s2 (strlang ?str "en-US")))
|
10
|
+
# (filter (langMatches (lang ?str) "en")
|
11
|
+
# (bgp (triple ?s :str ?str))))))
|
12
|
+
#
|
13
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-strlang
|
14
|
+
class StrLang < Operator::Binary
|
15
|
+
include Evaluatable
|
16
|
+
|
17
|
+
NAME = :strlang
|
18
|
+
|
19
|
+
##
|
20
|
+
# Constructs a literal with lexical form and type as specified by the arguments.
|
21
|
+
#
|
22
|
+
# @param [RDF::Literal] value
|
23
|
+
# a literal
|
24
|
+
# @param [RDF::Literal] datatypeIRI
|
25
|
+
# datatype
|
26
|
+
# @return [RDF::Literal] a datatyped literal
|
27
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-strlang
|
28
|
+
def apply(value, langTag)
|
29
|
+
raise TypeError, "Literal #{value.inspect} is not simple" unless value.simple?
|
30
|
+
RDF::Literal.new(value.to_s, :language => langTag.to_s)
|
31
|
+
end
|
32
|
+
end # StrLang
|
33
|
+
end # Operator
|
34
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# The SPARQL `strlen` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (strlen ?x)
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-strlen
|
10
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-string-length
|
11
|
+
class StrLen < Operator::Unary
|
12
|
+
include Evaluatable
|
13
|
+
|
14
|
+
NAME = :strlen
|
15
|
+
|
16
|
+
##
|
17
|
+
# The strlen function corresponds to the XPath fn:string-length function and returns an xsd:integer equal to the length in characters of the lexical form of the literal.
|
18
|
+
#
|
19
|
+
# @example
|
20
|
+
# strlen("chat") 4
|
21
|
+
# strlen("chat"@en) 4
|
22
|
+
# strlen("chat"^^xsd:string) 4
|
23
|
+
#
|
24
|
+
# @param [RDF::Literal] operand
|
25
|
+
# the operand
|
26
|
+
# @return [RDF::Literal::Integer] length of string
|
27
|
+
# @raise [TypeError] if the operand is not a numeric value
|
28
|
+
def apply(operand)
|
29
|
+
raise TypeError, "expected a plain RDF::Literal, but got #{operand.inspect}" unless operand.literal? && operand.plain?
|
30
|
+
RDF::Literal(operand.to_s.length)
|
31
|
+
end
|
32
|
+
end # StrLen
|
33
|
+
end # Operator
|
34
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# A SPARQL `strstarts` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (strstarts ?x ?y)
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-strstarts
|
10
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-starts-with
|
11
|
+
class StrStarts < Operator::Binary
|
12
|
+
include Evaluatable
|
13
|
+
|
14
|
+
NAME = :strstarts
|
15
|
+
|
16
|
+
##
|
17
|
+
# The STRSTARTS function corresponds to the XPath fn:starts-with function. The arguments must be argument compatible otherwise an error is raised.
|
18
|
+
#
|
19
|
+
# For such input pairs, the function returns true if the lexical form of arg1 starts with the lexical form of arg2, otherwise it returns false.
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# strStarts("foobar", "foo") #=> true
|
23
|
+
# strStarts("foobar"@en, "foo"@en) #=> true
|
24
|
+
# strStarts("foobar"^^xsd:string, "foo"^^xsd:string) #=> true
|
25
|
+
# strStarts("foobar"^^xsd:string, "foo") #=> true
|
26
|
+
# strStarts("foobar", "foo"^^xsd:string) #=> true
|
27
|
+
# strStarts("foobar"@en, "foo") #=> true
|
28
|
+
# strStarts("foobar"@en, "foo"^^xsd:string) #=> true
|
29
|
+
#
|
30
|
+
# @param [RDF::Literal] left
|
31
|
+
# a literal
|
32
|
+
# @param [RDF::Literal] right
|
33
|
+
# a literal
|
34
|
+
# @return [RDF::Literal::Boolean]
|
35
|
+
# @raise [TypeError] if operands are not compatible
|
36
|
+
def apply(left, right)
|
37
|
+
case
|
38
|
+
when !left.compatible?(right)
|
39
|
+
raise TypeError, "expected two RDF::Literal operands, but got #{left.inspect} and #{right.inspect}"
|
40
|
+
when left.to_s.start_with?(right.to_s) then RDF::Literal::TRUE
|
41
|
+
else RDF::Literal::FALSE
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end # StrStarts
|
45
|
+
end # Operator
|
46
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module SPARQL; module Algebra
|
4
|
+
class Operator
|
5
|
+
##
|
6
|
+
# The SPARQL `uuid` function.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# (prefix ((: <http://example.org/>)
|
10
|
+
# (xsd: <http://www.w3.org/2001/XMLSchema#>))
|
11
|
+
# (project (?length)
|
12
|
+
# (extend ((?length (strlen ?uuid)))
|
13
|
+
# (filter (&& (isLiteral ?uuid) (regex ?uuid "^[0-9A-F]{8}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{12}$" "i"))
|
14
|
+
# (extend ((?uuid (struuid)))
|
15
|
+
# (bgp))))))
|
16
|
+
#
|
17
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-struuid
|
18
|
+
class StrUUID < Operator::Nullary
|
19
|
+
include Evaluatable
|
20
|
+
|
21
|
+
NAME = :struuid
|
22
|
+
|
23
|
+
##
|
24
|
+
# Return a string that is the scheme specific part of UUID. That is, as a simple literal, the result of generating a UUID, converting to a simple literal and removing the initial urn:uuid:.
|
25
|
+
#
|
26
|
+
# @return [RDF::URI]
|
27
|
+
def apply
|
28
|
+
RDF::Literal(SecureRandom.uuid)
|
29
|
+
end
|
30
|
+
end # StrUUID
|
31
|
+
end # Operator
|
32
|
+
end; end # SPARQL::Algebra
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module SPARQL; module Algebra
|
2
|
+
class Operator
|
3
|
+
##
|
4
|
+
# A SPARQL `substr` operator.
|
5
|
+
#
|
6
|
+
# @example
|
7
|
+
# (substr ?x ?y)
|
8
|
+
#
|
9
|
+
# @see http://www.w3.org/TR/sparql11-query/#func-substr
|
10
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-substring
|
11
|
+
class SubStr < Operator::Ternary
|
12
|
+
include Evaluatable
|
13
|
+
|
14
|
+
NAME = :substr
|
15
|
+
|
16
|
+
##
|
17
|
+
# Initializes a new operator instance.
|
18
|
+
#
|
19
|
+
# @param [RDF::Literal] source
|
20
|
+
# @param [RDF::Litereal::Integer] startingLoc
|
21
|
+
# @param [RDF::Litereal::Integer] length (-1)
|
22
|
+
# @param [Hash{Symbol => Object}] options
|
23
|
+
# any additional options (see {Operator#initialize})
|
24
|
+
# @raise [TypeError] if any operand is invalid
|
25
|
+
def initialize(source, startingLoc, length = RDF::Literal(""), options = {})
|
26
|
+
super
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# The substr function corresponds to the XPath fn:substring function and returns a literal of the same kind (simple literal, literal with language tag, xsd:string typed literal) as the source input parameter but with a lexical form formed from the substring of the lexcial form of the source.
|
31
|
+
#
|
32
|
+
# The arguments startingLoc and length may be derived types of xsd:integer.
|
33
|
+
#
|
34
|
+
# The index of the first character in a strings is 1.
|
35
|
+
#
|
36
|
+
# @example
|
37
|
+
# substr("foobar", 4) #=> "bar"
|
38
|
+
# substr("foobar"@en, 4) #=> "bar"@en
|
39
|
+
# substr("foobar"^^xsd:string, 4) #=> "bar"^^xsd:string
|
40
|
+
# substr("foobar", 4, 1) #=> "b"
|
41
|
+
# substr("foobar"@en, 4, 1) #=> "b"@en
|
42
|
+
# substr("foobar"^^xsd:string, 4, 1) #=> "b"^^xsd:string
|
43
|
+
#
|
44
|
+
# @param [RDF::Literal] source
|
45
|
+
# a literal
|
46
|
+
# @param [RDF::Literal] startingLoc
|
47
|
+
# an 1-based integer offset into source
|
48
|
+
# @param [RDF::Literal::Integer] length (-1)
|
49
|
+
# an optional length of the substring.
|
50
|
+
# @return [RDF::Literal]
|
51
|
+
# @raise [TypeError] if operands are not compatible
|
52
|
+
def apply(source, startingLoc, length)
|
53
|
+
raise TypeError, "expected a plain RDF::Literal, but got #{source.inspect}" unless source.literal? && source.plain?
|
54
|
+
text = text.to_s
|
55
|
+
|
56
|
+
raise TypeError, "expected an integer, but got #{startingLoc.inspect}" unless startingLoc.is_a?(RDF::Literal::Integer)
|
57
|
+
startingLoc = startingLoc.to_i
|
58
|
+
|
59
|
+
if length == RDF::Literal("")
|
60
|
+
RDF::Literal(source.to_s[(startingLoc-1)..-1], :datatype => source.datatype, :language => source.language)
|
61
|
+
else
|
62
|
+
raise TypeError, "expected an integer, but got #{length.inspect}" unless length.is_a?(RDF::Literal::Integer)
|
63
|
+
length = length.to_i
|
64
|
+
RDF::Literal(source.to_s[(startingLoc-1), length], :datatype => source.datatype, :language => source.language)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
##
|
69
|
+
# Returns the SPARQL S-Expression (SSE) representation of this expression.
|
70
|
+
#
|
71
|
+
# Remove the optional argument.
|
72
|
+
#
|
73
|
+
# @return [Array] `self`
|
74
|
+
# @see http://openjena.org/wiki/SSE
|
75
|
+
def to_sxp_bin
|
76
|
+
[NAME] + operands.reject {|o| o.to_s == ""}
|
77
|
+
end
|
78
|
+
end # SubStr
|
79
|
+
end # Operator
|
80
|
+
end; end # SPARQL::Algebra
|