rdf 0.3.3 → 0.3.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.
- 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.
|