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
         |