rdf 0.3.3 → 0.3.4
Sign up to get free protection for your applications and to get access to all the features.
- data/README +107 -20
- data/VERSION +1 -1
- data/bin/rdf +4 -8
- data/etc/doap.nt +8 -8
- data/lib/rdf.rb +1 -0
- data/lib/rdf/cli.rb +146 -19
- data/lib/rdf/format.rb +59 -10
- data/lib/rdf/mixin/type_check.rb +21 -0
- data/lib/rdf/model/graph.rb +1 -0
- data/lib/rdf/model/list.rb +36 -3
- data/lib/rdf/model/literal.rb +113 -74
- data/lib/rdf/model/literal/boolean.rb +15 -5
- data/lib/rdf/model/literal/date.rb +24 -6
- data/lib/rdf/model/literal/datetime.rb +21 -4
- data/lib/rdf/model/literal/decimal.rb +3 -128
- data/lib/rdf/model/literal/double.rb +4 -107
- data/lib/rdf/model/literal/integer.rb +3 -97
- data/lib/rdf/model/literal/numeric.rb +178 -3
- data/lib/rdf/model/literal/time.rb +23 -3
- data/lib/rdf/model/literal/token.rb +2 -2
- data/lib/rdf/model/literal/xml.rb +1 -1
- data/lib/rdf/model/node.rb +35 -5
- data/lib/rdf/model/statement.rb +7 -6
- data/lib/rdf/model/term.rb +32 -0
- data/lib/rdf/model/uri.rb +13 -7
- data/lib/rdf/model/value.rb +10 -0
- data/lib/rdf/nquads.rb +120 -3
- data/lib/rdf/ntriples/format.rb +9 -1
- data/lib/rdf/ntriples/writer.rb +1 -0
- data/lib/rdf/query.rb +121 -13
- data/lib/rdf/query/pattern.rb +28 -15
- data/lib/rdf/query/solution.rb +47 -0
- data/lib/rdf/query/solutions.rb +45 -10
- data/lib/rdf/query/variable.rb +39 -4
- data/lib/rdf/reader.rb +47 -4
- data/lib/rdf/repository.rb +8 -4
- data/lib/rdf/util/file.rb +5 -2
- data/lib/rdf/version.rb +1 -1
- data/lib/rdf/writer.rb +34 -5
- metadata +56 -88
@@ -9,20 +9,19 @@ module RDF; class Literal
|
|
9
9
|
# RDF::Literal(84) / 2 #=> RDF::Literal(42)
|
10
10
|
#
|
11
11
|
# @see http://www.w3.org/TR/xmlschema-2/#integer
|
12
|
+
# @see http://www.w3.org/TR/2004/REC-xmlschema-2-20041028/#integer
|
12
13
|
# @since 0.2.1
|
13
14
|
class Integer < Decimal
|
14
15
|
DATATYPE = XSD.integer
|
15
16
|
GRAMMAR = /^[\+\-]?\d+$/.freeze
|
16
17
|
|
17
|
-
include RDF::Literal::Numeric
|
18
|
-
|
19
18
|
##
|
20
19
|
# @param [Integer, #to_i] value
|
21
20
|
# @option options [String] :lexical (nil)
|
22
21
|
def initialize(value, options = {})
|
23
|
-
@datatype = RDF::URI(options[:datatype] || DATATYPE)
|
22
|
+
@datatype = RDF::URI(options[:datatype] || self.class.const_get(:DATATYPE))
|
24
23
|
@string = options[:lexical] if options.has_key?(:lexical)
|
25
|
-
@string
|
24
|
+
@string ||= value if value.is_a?(String)
|
26
25
|
@object = case
|
27
26
|
when value.is_a?(::String) then Integer(value) rescue nil
|
28
27
|
when value.is_a?(::Integer) then value
|
@@ -105,65 +104,6 @@ module RDF; class Literal
|
|
105
104
|
to_i.nonzero? ? self : nil
|
106
105
|
end
|
107
106
|
|
108
|
-
##
|
109
|
-
# Returns `self`.
|
110
|
-
#
|
111
|
-
# @return [RDF::Literal]
|
112
|
-
# @since 0.2.3
|
113
|
-
def +@
|
114
|
-
self # unary plus
|
115
|
-
end
|
116
|
-
|
117
|
-
##
|
118
|
-
# Returns `self` negated.
|
119
|
-
#
|
120
|
-
# @return [RDF::Literal]
|
121
|
-
# @since 0.2.3
|
122
|
-
def -@
|
123
|
-
RDF::Literal(-to_i) # unary minus
|
124
|
-
end
|
125
|
-
|
126
|
-
##
|
127
|
-
# Returns the sum of `self` plus `other`.
|
128
|
-
#
|
129
|
-
# @param [#to_i] other
|
130
|
-
# @return [RDF::Literal]
|
131
|
-
# @since 0.2.3
|
132
|
-
def +(other)
|
133
|
-
RDF::Literal(to_i + other.to_i)
|
134
|
-
end
|
135
|
-
|
136
|
-
##
|
137
|
-
# Returns the difference of `self` minus `other`.
|
138
|
-
#
|
139
|
-
# @param [#to_i] other
|
140
|
-
# @return [RDF::Literal]
|
141
|
-
# @since 0.2.3
|
142
|
-
def -(other)
|
143
|
-
RDF::Literal(to_i - other.to_i)
|
144
|
-
end
|
145
|
-
|
146
|
-
##
|
147
|
-
# Returns the product of `self` times `other`.
|
148
|
-
#
|
149
|
-
# @param [#to_i] other
|
150
|
-
# @return [RDF::Literal]
|
151
|
-
# @since 0.2.3
|
152
|
-
def *(other)
|
153
|
-
RDF::Literal(to_i * other.to_i)
|
154
|
-
end
|
155
|
-
|
156
|
-
##
|
157
|
-
# Returns the quotient of `self` divided by `other`.
|
158
|
-
#
|
159
|
-
# @param [#to_i] other
|
160
|
-
# @return [RDF::Literal]
|
161
|
-
# @raise [ZeroDivisionError] if divided by zero
|
162
|
-
# @since 0.2.3
|
163
|
-
def /(other)
|
164
|
-
RDF::Literal(to_i / other.to_i)
|
165
|
-
end
|
166
|
-
|
167
107
|
##
|
168
108
|
# Returns the value as a string.
|
169
109
|
#
|
@@ -172,40 +112,6 @@ module RDF; class Literal
|
|
172
112
|
@string || @object.to_s
|
173
113
|
end
|
174
114
|
|
175
|
-
##
|
176
|
-
# Returns the value as an integer.
|
177
|
-
#
|
178
|
-
# @return [Integer]
|
179
|
-
def to_i
|
180
|
-
@object.to_i
|
181
|
-
end
|
182
|
-
alias_method :to_int, :to_i
|
183
|
-
alias_method :ord, :to_i
|
184
|
-
|
185
|
-
##
|
186
|
-
# Returns the value as a floating point number.
|
187
|
-
#
|
188
|
-
# @return [Float]
|
189
|
-
def to_f
|
190
|
-
@object.to_f
|
191
|
-
end
|
192
|
-
|
193
|
-
##
|
194
|
-
# Returns the value as a decimal number.
|
195
|
-
#
|
196
|
-
# @return [BigDecimal]
|
197
|
-
def to_d
|
198
|
-
@object.respond_to?(:to_d) ? @object.to_d : BigDecimal(@object.to_s)
|
199
|
-
end
|
200
|
-
|
201
|
-
##
|
202
|
-
# Returns the value as a rational number.
|
203
|
-
#
|
204
|
-
# @return [Rational]
|
205
|
-
def to_r
|
206
|
-
@object.to_r
|
207
|
-
end
|
208
|
-
|
209
115
|
##
|
210
116
|
# Returns the value as an `OpenSSL::BN` instance.
|
211
117
|
#
|
@@ -1,9 +1,184 @@
|
|
1
1
|
module RDF; class Literal
|
2
2
|
##
|
3
|
-
# Shared methods for numeric literal classes.
|
3
|
+
# Shared methods and class ancestry for numeric literal classes.
|
4
4
|
#
|
5
5
|
# @since 0.3.0
|
6
|
-
|
7
|
-
|
6
|
+
class Numeric < Literal
|
7
|
+
##
|
8
|
+
# Compares this literal to `other` for sorting purposes.
|
9
|
+
#
|
10
|
+
# @param [Object] other
|
11
|
+
# @return [Integer] `-1`, `0`, or `1`
|
12
|
+
# @since 0.3.0
|
13
|
+
def <=>(other)
|
14
|
+
case other
|
15
|
+
when ::Numeric
|
16
|
+
to_d <=> other
|
17
|
+
when Numeric
|
18
|
+
to_d <=> other.to_d
|
19
|
+
else super
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Returns `true` if this literal is equal to `other`.
|
25
|
+
#
|
26
|
+
# @param [Object] other
|
27
|
+
# @return [Boolean] `true` or `false`
|
28
|
+
# @since 0.3.0
|
29
|
+
def ==(other)
|
30
|
+
# If lexically invalid, use regular literal testing
|
31
|
+
return super unless self.valid?
|
32
|
+
|
33
|
+
case other
|
34
|
+
when Literal::Numeric
|
35
|
+
return super unless other.valid?
|
36
|
+
(cmp = (self <=> other)) ? cmp.zero? : false
|
37
|
+
when RDF::URI, RDF::Node
|
38
|
+
# Interpreting SPARQL data-r2/expr-equal/eq-2-2, numeric can't be compared with other types
|
39
|
+
type_error("unable to determine whether #{self.inspect} and #{other.inspect} are equivalent")
|
40
|
+
else
|
41
|
+
super
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
##
|
46
|
+
# Returns `self`.
|
47
|
+
#
|
48
|
+
# @return [RDF::Literal::Numeric]
|
49
|
+
# @since 0.2.3
|
50
|
+
def +@
|
51
|
+
self # unary plus
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Returns `self` negated.
|
56
|
+
#
|
57
|
+
# @return [RDF::Literal::Numeric]
|
58
|
+
# @since 0.2.3
|
59
|
+
def -@
|
60
|
+
self.class.new(-self.object)
|
61
|
+
end
|
62
|
+
|
63
|
+
##
|
64
|
+
# Returns the sum of `self` plus `other`.
|
65
|
+
#
|
66
|
+
# For xs:float or xs:double values, if one of the operands is a zero or a finite number
|
67
|
+
# and the other is INF or -INF, INF or -INF is returned. If both operands are INF, INF is returned.
|
68
|
+
# If both operands are -INF, -INF is returned. If one of the operands is INF
|
69
|
+
# and the other is -INF, NaN is returned.
|
70
|
+
# @param [Literal::Numeric, #to_i, #to_f, #to_d] other
|
71
|
+
# @return [RDF::Literal::Numeric]
|
72
|
+
# @since 0.2.3
|
73
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-numeric-add
|
74
|
+
def +(other)
|
75
|
+
if self.class == Double || other.class == Double
|
76
|
+
RDF::Literal::Double.new(to_f + other.to_f)
|
77
|
+
elsif self.class == Float || other.class == Float
|
78
|
+
RDF::Literal::Float.new(to_f + other.to_f)
|
79
|
+
elsif self.class == Decimal || other.class == Decimal
|
80
|
+
RDF::Literal::Decimal.new(to_d + (other.respond_to?(:to_d) ? other.to_d : BigDecimal(other.to_s)))
|
81
|
+
else
|
82
|
+
RDF::Literal::Integer.new(to_i + other.to_i)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
##
|
87
|
+
# Returns the difference of `self` minus `other`.
|
88
|
+
#
|
89
|
+
# @param [Literal::Numeric, #to_i, #to_f, #to_d] other
|
90
|
+
# @return [RDF::Literal::Numeric]
|
91
|
+
# @since 0.2.3
|
92
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-numeric-subtract
|
93
|
+
def -(other)
|
94
|
+
if self.class == Double || other.class == Double
|
95
|
+
RDF::Literal::Double.new(to_f - other.to_f)
|
96
|
+
elsif self.class == Float || other.class == Float
|
97
|
+
RDF::Literal::Float.new(to_f - other.to_f)
|
98
|
+
elsif self.class == Decimal || other.class == Decimal
|
99
|
+
RDF::Literal::Decimal.new(to_d - (other.respond_to?(:to_d) ? other.to_d : BigDecimal(other.to_s)))
|
100
|
+
else
|
101
|
+
RDF::Literal::Integer.new(to_i - other.to_i)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# Returns the product of `self` times `other`.
|
107
|
+
#
|
108
|
+
# @param [Literal::Numeric, #to_i, #to_f, #to_d] other
|
109
|
+
# @return [RDF::Literal::Numeric]
|
110
|
+
# @since 0.2.3
|
111
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-numeric-multiply
|
112
|
+
def *(other)
|
113
|
+
if self.class == Double || other.class == Double
|
114
|
+
RDF::Literal::Double.new(to_f * other.to_f)
|
115
|
+
elsif self.class == Float || other.class == Float
|
116
|
+
RDF::Literal::Float.new(to_f * other.to_f)
|
117
|
+
elsif self.class == Decimal || other.class == Decimal
|
118
|
+
RDF::Literal::Decimal.new(to_d * (other.respond_to?(:to_d) ? other.to_d : BigDecimal(other.to_s)))
|
119
|
+
else
|
120
|
+
RDF::Literal::Integer.new(to_i * other.to_i)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
##
|
125
|
+
# Returns the quotient of `self` divided by `other`.
|
126
|
+
#
|
127
|
+
# As a special case, if the types of both $arg1 and $arg2 are xs:integer,
|
128
|
+
# then the return type is xs:decimal.
|
129
|
+
#
|
130
|
+
# @param [Literal::Numeric, #to_i, #to_f, #to_d] other
|
131
|
+
# @return [RDF::Literal::Numeric]
|
132
|
+
# @raise [ZeroDivisionError] if divided by zero
|
133
|
+
# @since 0.2.3
|
134
|
+
# @see http://www.w3.org/TR/xpath-functions/#func-numeric-divide
|
135
|
+
def /(other)
|
136
|
+
if self.class == Double || other.class == Double
|
137
|
+
RDF::Literal::Double.new(to_f / other.to_f)
|
138
|
+
elsif self.class == Float || other.class == Float
|
139
|
+
RDF::Literal::Float.new(to_f / other.to_f)
|
140
|
+
elsif self.class == Decimal || other.class == Decimal
|
141
|
+
RDF::Literal::Decimal.new(to_d / (other.respond_to?(:to_d) ? other.to_d : BigDecimal(other.to_s)))
|
142
|
+
else
|
143
|
+
RDF::Literal::Integer.new(to_i / other.to_i)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
##
|
148
|
+
# Returns the value as an integer.
|
149
|
+
#
|
150
|
+
# @return [Integer]
|
151
|
+
def to_i
|
152
|
+
@object.to_i
|
153
|
+
end
|
154
|
+
alias_method :to_int, :to_i
|
155
|
+
alias_method :ord, :to_i
|
156
|
+
|
157
|
+
##
|
158
|
+
# Returns the value as a floating point number.
|
159
|
+
#
|
160
|
+
# The usual accuracy limits and errors of binary float arithmetic apply.
|
161
|
+
#
|
162
|
+
# @return [Float]
|
163
|
+
# @see BigDecimal#to_f
|
164
|
+
def to_f
|
165
|
+
@object.to_f
|
166
|
+
end
|
167
|
+
|
168
|
+
##
|
169
|
+
# Returns the value as a decimal number.
|
170
|
+
#
|
171
|
+
# @return [BigDecimal]
|
172
|
+
def to_d
|
173
|
+
@object.respond_to?(:to_d) ? @object.to_d : BigDecimal(@object.to_s)
|
174
|
+
end
|
175
|
+
|
176
|
+
##
|
177
|
+
# Returns the value as a rational number.
|
178
|
+
#
|
179
|
+
# @return [Rational]
|
180
|
+
def to_r
|
181
|
+
@object.to_r
|
182
|
+
end
|
8
183
|
end # Numeric
|
9
184
|
end; end # RDF::Literal
|
@@ -1,3 +1,4 @@
|
|
1
|
+
# coding: utf-8
|
1
2
|
module RDF; class Literal
|
2
3
|
##
|
3
4
|
# A time literal.
|
@@ -16,14 +17,14 @@ module RDF; class Literal
|
|
16
17
|
# @param [Time] value
|
17
18
|
# @option options [String] :lexical (nil)
|
18
19
|
def initialize(value, options = {})
|
19
|
-
@datatype = RDF::URI(options[:datatype] || DATATYPE)
|
20
|
+
@datatype = RDF::URI(options[:datatype] || self.class.const_get(:DATATYPE))
|
20
21
|
@string = options[:lexical] if options.has_key?(:lexical)
|
21
|
-
@string
|
22
|
+
@string ||= value if value.is_a?(String)
|
22
23
|
@object = case
|
23
24
|
when value.is_a?(::Time) then value
|
24
25
|
when value.respond_to?(:to_time) then value.to_time # Ruby 1.9+
|
25
26
|
else ::Time.parse(value.to_s)
|
26
|
-
end
|
27
|
+
end rescue nil
|
27
28
|
end
|
28
29
|
|
29
30
|
##
|
@@ -51,5 +52,24 @@ module RDF; class Literal
|
|
51
52
|
def to_s
|
52
53
|
@string || @object.strftime('%H:%M:%S%Z').sub(/\+00:00|UTC/, 'Z')
|
53
54
|
end
|
55
|
+
|
56
|
+
##
|
57
|
+
# Equal compares as Time objects
|
58
|
+
def ==(other)
|
59
|
+
# If lexically invalid, use regular literal testing
|
60
|
+
return super unless self.valid?
|
61
|
+
|
62
|
+
case other
|
63
|
+
when Literal::Time
|
64
|
+
return super unless other.valid?
|
65
|
+
# Compare as strings, as time includes a date portion, and adjusting for UTC
|
66
|
+
# can create a mismatch in the date portion.
|
67
|
+
self.object.utc.strftime('%H%M%S') == other.object.utc.strftime('%H%M%S')
|
68
|
+
when Literal::DateTime, Literal::Date
|
69
|
+
false
|
70
|
+
else
|
71
|
+
super
|
72
|
+
end
|
73
|
+
end
|
54
74
|
end # Time
|
55
75
|
end; end # RDF::Literal
|
@@ -12,9 +12,9 @@ module RDF; class Literal
|
|
12
12
|
# @param [Symbol, #to_s] value
|
13
13
|
# @option options [String] :lexical (nil)
|
14
14
|
def initialize(value, options = {})
|
15
|
-
@datatype = RDF::URI(options[:datatype] || DATATYPE)
|
15
|
+
@datatype = RDF::URI(options[:datatype] || self.class.const_get(:DATATYPE))
|
16
16
|
@string = options[:lexical] if options.has_key?(:lexical)
|
17
|
-
@string
|
17
|
+
@string ||= value if value.is_a?(String)
|
18
18
|
@object = value.is_a?(Symbol) ? value : value.to_s
|
19
19
|
end
|
20
20
|
|
@@ -13,7 +13,7 @@ module RDF; class Literal
|
|
13
13
|
# @param [Object] value
|
14
14
|
# @option options [String] :lexical (nil)
|
15
15
|
def initialize(value, options = {})
|
16
|
-
@datatype = options[:datatype] || DATATYPE
|
16
|
+
@datatype = options[:datatype] || self.class.const_get(:DATATYPE)
|
17
17
|
@string = options[:lexical] if options.has_key?(:lexical)
|
18
18
|
@object = value # TODO: parse XML string using REXML
|
19
19
|
end
|
data/lib/rdf/model/node.rb
CHANGED
@@ -44,6 +44,23 @@ module RDF
|
|
44
44
|
self.new(id)
|
45
45
|
end
|
46
46
|
|
47
|
+
##
|
48
|
+
# Override #dup to remember original object.
|
49
|
+
# This allows .eql? to determine that two nodes
|
50
|
+
# are the same thing, and not different nodes
|
51
|
+
# instantiated with the same identifier.
|
52
|
+
# @return [RDF::Node]
|
53
|
+
def dup
|
54
|
+
node = super
|
55
|
+
node.original = self.original || self
|
56
|
+
node
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# Originally instantiated node, if any
|
61
|
+
# @return [RDF::Node]
|
62
|
+
attr_accessor :original
|
63
|
+
|
47
64
|
# @return [String]
|
48
65
|
attr_accessor :id
|
49
66
|
|
@@ -88,23 +105,36 @@ module RDF
|
|
88
105
|
end
|
89
106
|
|
90
107
|
##
|
91
|
-
#
|
108
|
+
# Determins if `self` is the same term as `other`.
|
109
|
+
#
|
110
|
+
# In this case, nodes must be the same object
|
92
111
|
#
|
93
112
|
# @param [Node] other
|
94
113
|
# @return [Boolean]
|
95
114
|
def eql?(other)
|
96
|
-
other.is_a?(Node) && self
|
115
|
+
other.is_a?(RDF::Node) && (self.original || self).equal?(other.original || other)
|
97
116
|
end
|
98
117
|
|
99
118
|
##
|
100
|
-
# Checks whether this blank node is equal to `other
|
119
|
+
# Checks whether this blank node is equal to `other` (type checking).
|
120
|
+
#
|
121
|
+
# In this case, different nodes having the same id are considered the same.
|
122
|
+
#
|
123
|
+
# Per SPARQL data-r2/expr-equal/eq-2-2, numeric can't be compared with other types
|
101
124
|
#
|
102
125
|
# @param [Object] other
|
103
126
|
# @return [Boolean]
|
127
|
+
# @see http://www.w3.org/TR/rdf-sparql-query/#func-RDFterm-equal
|
104
128
|
def ==(other)
|
105
|
-
|
106
|
-
|
129
|
+
case other
|
130
|
+
when Literal
|
131
|
+
# If other is a Literal, reverse test to consolodate complex type checking logic
|
132
|
+
other == self
|
133
|
+
else
|
134
|
+
other.respond_to?(:node?) && other.node? && other.respond_to?(:id) && @id == other.id
|
135
|
+
end
|
107
136
|
end
|
137
|
+
alias_method :===, :==
|
108
138
|
|
109
139
|
##
|
110
140
|
# Returns a string representation of this blank node.
|