rdf 3.2.3 → 3.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +37 -37
- data/VERSION +1 -1
- data/lib/rdf/mixin/countable.rb +5 -1
- data/lib/rdf/mixin/enumerable.rb +13 -1
- data/lib/rdf/mixin/queryable.rb +13 -1
- data/lib/rdf/model/list.rb +1 -1
- data/lib/rdf/model/literal/date.rb +27 -82
- data/lib/rdf/model/literal/datetime.rb +22 -122
- data/lib/rdf/model/literal/decimal.rb +12 -0
- data/lib/rdf/model/literal/double.rb +20 -0
- data/lib/rdf/model/literal/integer.rb +6 -0
- data/lib/rdf/model/literal/numeric.rb +154 -4
- data/lib/rdf/model/literal/temporal.rb +310 -0
- data/lib/rdf/model/literal/time.rb +29 -98
- data/lib/rdf/model/literal.rb +2 -1
- data/lib/rdf/model/statement.rb +3 -1
- data/lib/rdf/model/uri.rb +3 -2
- data/lib/rdf/ntriples/reader.rb +1 -1
- data/lib/rdf/query/solution.rb +1 -2
- data/lib/rdf/query/solutions.rb +21 -0
- data/lib/rdf/vocab/owl.rb +450 -445
- data/lib/rdf/vocab/rdfs.rb +89 -88
- data/lib/rdf/vocab/writer.rb +84 -51
- data/lib/rdf/vocab/xsd.rb +249 -249
- data/lib/rdf/vocabulary.rb +109 -124
- data/lib/rdf.rb +0 -3
- metadata +11 -5
- data/lib/rdf/mixin/enumerator.rb +0 -40
@@ -9,91 +9,44 @@ module RDF; class Literal
|
|
9
9
|
#
|
10
10
|
# @see http://www.w3.org/TR/xmlschema11-2/#time
|
11
11
|
# @since 0.2.1
|
12
|
-
class Time <
|
12
|
+
class Time < Temporal
|
13
13
|
DATATYPE = RDF::URI("http://www.w3.org/2001/XMLSchema#time")
|
14
14
|
GRAMMAR = %r(\A(\d{2}:\d{2}:\d{2}(?:\.\d+)?)((?:[\+\-]\d{2}:\d{2})|UTC|GMT|Z)?\Z).freeze
|
15
|
-
FORMAT = '%H:%M:%S.%L
|
15
|
+
FORMAT = '%H:%M:%S.%L'.freeze
|
16
16
|
|
17
17
|
##
|
18
|
+
# Internally, a `DateTime` is represented using a native `::DateTime`. If initialized from a `::DateTime`, the timezone is taken from that native object, otherwise, a timezone (or no timezone) is taken from the string representation having a matching `zzzzzz` component.
|
19
|
+
#
|
18
20
|
# @param [String, DateTime, #to_datetime] value
|
19
21
|
# @param (see Literal#initialize)
|
20
22
|
def initialize(value, datatype: nil, lexical: nil, **options)
|
21
23
|
@datatype = RDF::URI(datatype || self.class.const_get(:DATATYPE))
|
22
24
|
@string = lexical || (value if value.is_a?(String))
|
23
25
|
@object = case
|
24
|
-
when value.
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
##
|
31
|
-
# Converts this literal into its canonical lexical representation.
|
32
|
-
#
|
33
|
-
# §3.2.8.2 Canonical representation
|
34
|
-
#
|
35
|
-
# The canonical representation for time is defined by prohibiting
|
36
|
-
# certain options from the Lexical representation (§3.2.8.1).
|
37
|
-
# Specifically, either the time zone must be omitted or, if present, the
|
38
|
-
# time zone must be Coordinated Universal Time (UTC) indicated by a "Z".
|
39
|
-
# Additionally, the canonical representation for midnight is 00:00:00.
|
40
|
-
#
|
41
|
-
# @return [RDF::Literal] `self`
|
42
|
-
# @see http://www.w3.org/TR/xmlschema11-2/#time
|
43
|
-
def canonicalize!
|
44
|
-
if self.valid?
|
45
|
-
@string = if timezone?
|
46
|
-
@object.new_offset.new_offset.strftime(FORMAT[0..-4] + 'Z').sub('.000', '')
|
26
|
+
when value.respond_to?(:to_datetime)
|
27
|
+
dt = value.to_datetime
|
28
|
+
@zone = dt.zone
|
29
|
+
# Normalize to 1972-12-31 dateTime base
|
30
|
+
hms = dt.strftime(FORMAT)
|
31
|
+
::DateTime.parse("1972-12-31T#{hms}#{@zone}")
|
47
32
|
else
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
##
|
66
|
-
# Returns `true` if the value adheres to the defined grammar of the
|
67
|
-
# datatype.
|
68
|
-
#
|
69
|
-
# Special case for date and dateTime, for which '0000' is not a valid year
|
70
|
-
#
|
71
|
-
# @return [Boolean]
|
72
|
-
# @since 0.2.1
|
73
|
-
def valid?
|
74
|
-
super && !object.nil?
|
75
|
-
end
|
76
|
-
|
77
|
-
##
|
78
|
-
# Does the literal representation include a timezone? Note that this is only possible if initialized using a string, or `:lexical` option.
|
79
|
-
#
|
80
|
-
# @return [Boolean]
|
81
|
-
# @since 1.1.6
|
82
|
-
def timezone?
|
83
|
-
md = self.to_s.match(GRAMMAR)
|
84
|
-
md && !!md[2]
|
85
|
-
end
|
86
|
-
alias_method :tz?, :timezone?
|
87
|
-
alias_method :has_tz?, :timezone?
|
88
|
-
alias_method :has_timezone?, :timezone?
|
89
|
-
|
90
|
-
##
|
91
|
-
# Returns the value as a string.
|
92
|
-
# Does not normalize timezone
|
93
|
-
#
|
94
|
-
# @return [String]
|
95
|
-
def to_s
|
96
|
-
@string || @object.strftime(FORMAT).sub("+00:00", 'Z').sub('.000', '')
|
33
|
+
md = value.to_s.match(GRAMMAR)
|
34
|
+
_, tm, tz = Array(md)
|
35
|
+
if tz
|
36
|
+
@zone = tz == 'Z' ? '+00:00' : tz
|
37
|
+
else
|
38
|
+
@zone = nil # No timezone
|
39
|
+
end
|
40
|
+
# Normalize 24:00:00 to 00:00:00
|
41
|
+
hr, mi, se = tm.split(':')
|
42
|
+
if hr.to_i > 23
|
43
|
+
hr = "%.2i" % (hr.to_i % 24)
|
44
|
+
@string = nil
|
45
|
+
end
|
46
|
+
value = "#{hr}:#{mi}:#{se}"
|
47
|
+
# Normalize to 1972-12-31 dateTime base
|
48
|
+
::DateTime.parse("1972-12-31T#{hr}:#{mi}:#{se}#{@zone}")
|
49
|
+
end rescue ::DateTime.new
|
97
50
|
end
|
98
51
|
|
99
52
|
##
|
@@ -104,32 +57,10 @@ module RDF; class Literal
|
|
104
57
|
def humanize(lang = :en)
|
105
58
|
t = object.strftime("%r")
|
106
59
|
if timezone?
|
107
|
-
|
108
|
-
|
109
|
-
else
|
110
|
-
" #{self.tz}"
|
111
|
-
end
|
60
|
+
z = @zone == '+00:00' ? "UTC" : @zone
|
61
|
+
t += " #{z}"
|
112
62
|
end
|
113
63
|
t
|
114
64
|
end
|
115
|
-
|
116
|
-
##
|
117
|
-
# Equal compares as Time objects
|
118
|
-
def ==(other)
|
119
|
-
# If lexically invalid, use regular literal testing
|
120
|
-
return super unless self.valid?
|
121
|
-
|
122
|
-
case other
|
123
|
-
when Literal::Time
|
124
|
-
return super unless other.valid?
|
125
|
-
# Compare as strings, as time includes a date portion, and adjusting for UTC
|
126
|
-
# can create a mismatch in the date portion.
|
127
|
-
self.object.new_offset.strftime('%H%M%S.%L') == other.object.new_offset.strftime('%H%M%S.%L')
|
128
|
-
when Literal::DateTime, Literal::Date
|
129
|
-
false
|
130
|
-
else
|
131
|
-
super
|
132
|
-
end
|
133
|
-
end
|
134
65
|
end # Time
|
135
66
|
end; end # RDF::Literal
|
data/lib/rdf/model/literal.rb
CHANGED
@@ -77,6 +77,7 @@ module RDF
|
|
77
77
|
require 'rdf/model/literal/decimal'
|
78
78
|
require 'rdf/model/literal/integer'
|
79
79
|
require 'rdf/model/literal/double'
|
80
|
+
require 'rdf/model/literal/temporal'
|
80
81
|
require 'rdf/model/literal/date'
|
81
82
|
require 'rdf/model/literal/datetime'
|
82
83
|
require 'rdf/model/literal/time'
|
@@ -295,7 +296,7 @@ module RDF
|
|
295
296
|
when self.simple? && other.simple?
|
296
297
|
self.value_hash == other.value_hash && self.value == other.value
|
297
298
|
when other.comperable_datatype?(self) || self.comperable_datatype?(other)
|
298
|
-
#
|
299
|
+
# Comparing plain with undefined datatypes does not generate an error, but returns false
|
299
300
|
# From data-r2/expr-equal/eq-2-2.
|
300
301
|
false
|
301
302
|
else
|
data/lib/rdf/model/statement.rb
CHANGED
@@ -71,6 +71,7 @@ module RDF
|
|
71
71
|
# @option options [RDF::Term] :graph_name (nil)
|
72
72
|
# Note, in RDF 1.1, a graph name MUST be an {Resource}.
|
73
73
|
# @option options [Boolean] :inferred used as a marker to record that this statement was inferred based on semantic relationships (T-Box).
|
74
|
+
# @option options [Boolean] :quoted used as a marker to record that this statement quoted and appears as the subject or object of another RDF::Statement.
|
74
75
|
# @return [RDF::Statement]
|
75
76
|
#
|
76
77
|
# @overload initialize(subject, predicate, object, **options)
|
@@ -83,6 +84,7 @@ module RDF
|
|
83
84
|
# @option options [RDF::Term] :graph_name (nil)
|
84
85
|
# Note, in RDF 1.1, a graph name MUST be an {Resource}.
|
85
86
|
# @option options [Boolean] :inferred used as a marker to record that this statement was inferred based on semantic relationships (T-Box).
|
87
|
+
# @option options [Boolean] :quoted used as a marker to record that this statement quoted and appears as the subject or object of another RDF::Statement.
|
86
88
|
# @return [RDF::Statement]
|
87
89
|
def initialize(subject = nil, predicate = nil, object = nil, options = {})
|
88
90
|
if subject.is_a?(Hash)
|
@@ -209,7 +211,7 @@ module RDF
|
|
209
211
|
##
|
210
212
|
# @return [Boolean]
|
211
213
|
def quoted?
|
212
|
-
|
214
|
+
!!@options[:quoted]
|
213
215
|
end
|
214
216
|
|
215
217
|
##
|
data/lib/rdf/model/uri.rb
CHANGED
@@ -112,8 +112,9 @@ module RDF
|
|
112
112
|
).freeze
|
113
113
|
|
114
114
|
# Characters in a PName which must be escaped
|
115
|
-
|
116
|
-
|
115
|
+
# Note: not all reserved characters need to be escaped in SPARQL/Turtle, but they must be unescaped when encountered
|
116
|
+
PN_ESCAPE_CHARS = /[~\.!\$&'\(\)\*\+,;=\/\?\#@%]/.freeze
|
117
|
+
PN_ESCAPES = /\\#{Regexp.union(PN_ESCAPE_CHARS, /[\-_]/)}/.freeze
|
117
118
|
|
118
119
|
##
|
119
120
|
# Cache size may be set through {RDF.config} using `uri_cache_size`.
|
data/lib/rdf/ntriples/reader.rb
CHANGED
@@ -255,7 +255,7 @@ module RDF::NTriples
|
|
255
255
|
if !match(ST_END)
|
256
256
|
log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
|
257
257
|
end
|
258
|
-
RDF::Statement.new(subject, predicate, object)
|
258
|
+
RDF::Statement.new(subject, predicate, object, quoted: true)
|
259
259
|
end
|
260
260
|
end
|
261
261
|
|
data/lib/rdf/query/solution.rb
CHANGED
@@ -317,13 +317,12 @@ class RDF::Query
|
|
317
317
|
def hash
|
318
318
|
@bindings.hash
|
319
319
|
end
|
320
|
-
|
320
|
+
|
321
321
|
##
|
322
322
|
# Equivalence of solution
|
323
323
|
def eql?(other)
|
324
324
|
other.is_a?(Solution) && @bindings.eql?(other.bindings)
|
325
325
|
end
|
326
|
-
alias_method :==, :eql?
|
327
326
|
|
328
327
|
##
|
329
328
|
# Equals of solution
|
data/lib/rdf/query/solutions.rb
CHANGED
@@ -77,6 +77,15 @@ module RDF; class Query
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
##
|
81
|
+
# Sets variable names used in these solutions. If not set, the default is determined by the variables used in each solution.
|
82
|
+
#
|
83
|
+
# @param [Array<Symbol, RDF::Query::Variable>] vars
|
84
|
+
# @return [Array<Symbol>]
|
85
|
+
def variable_names=(vars)
|
86
|
+
@variable_names = vars.map(&:to_sym)
|
87
|
+
end
|
88
|
+
|
80
89
|
##
|
81
90
|
# @overload variable?
|
82
91
|
# Returns `false`.
|
@@ -294,5 +303,17 @@ module RDF; class Query
|
|
294
303
|
self
|
295
304
|
end
|
296
305
|
alias_method :limit!, :limit
|
306
|
+
|
307
|
+
##
|
308
|
+
# Equivalence of solution
|
309
|
+
def eql?(other)
|
310
|
+
super && (!other.respond_to?(:variable_names) || variable_names.eql?(other.variable_names))
|
311
|
+
end
|
312
|
+
|
313
|
+
##
|
314
|
+
# Equals of solution
|
315
|
+
def ==(other)
|
316
|
+
super && (!other.respond_to?(:variable_names) || variable_names.eql?(other.variable_names))
|
317
|
+
end
|
297
318
|
end # Solutions
|
298
319
|
end; end # RDF::Query
|