rdf 3.2.3 → 3.2.6
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 +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
|