Skip to content

Commit 5eca224

Browse files
committed
Release 2.1.1.
2 parents aeb042e + b6cbe93 commit 5eca224

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+732
-177
lines changed

.travis.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,13 @@ script: "bundle exec rspec spec"
44
env:
55
- CI=true
66
rvm:
7-
- 2.2.5
8-
- 2.3.1
7+
- 2.2.6
8+
- 2.3.3
99
- jruby
1010
- rbx
1111
cache: bundler
1212
sudo: false
13-
addons:
14-
code_climate:
15-
repo_token: 5806cc8a21c03f4e2f9d3b9d98d5d9fe084b66243b1dbb27b467dbc795acdcac
1613
matrix:
1714
allow_failures:
1815
- rvm: jruby
16+
- rvm: rbx

Gemfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ group :develop do
66
gem 'rdf-isomorphic', github: "ruby-rdf/rdf-isomorphic", branch: "develop"
77
gem "rdf-reasoner", github: "ruby-rdf/rdf-reasoner", branch: "develop"
88
gem "rdf-spec", github: "ruby-rdf/rdf-spec", branch: "develop"
9+
gem "rdf-turtle", github: "ruby-rdf/rdf-turtle", branch: "develop"
910
gem "rdf-vocab", github: "ruby-rdf/rdf-vocab", branch: "develop"
1011
gem "rdf-xsd", github: "ruby-rdf/rdf-xsd", branch: "develop"
1112

@@ -27,7 +28,6 @@ group :test do
2728
gem 'fasterer'
2829
gem 'simplecov', require: false, platform: :mri
2930
gem 'coveralls', require: false, platform: :mri
30-
gem "codeclimate-test-reporter", require: false
3131
end
3232

3333
platforms :rbx do

README.md

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ This is a pure-Ruby library for working with [Resource Description Framework
1111

1212
[![Gem Version](https://badge.fury.io/rb/rdf.png)](http://badge.fury.io/rb/rdf)
1313
[![Build Status](https://travis-ci.org/ruby-rdf/rdf.png?branch=master)](http://travis-ci.org/ruby-rdf/rdf)
14-
[![Code Climate](https://codeclimate.com/github/ruby-rdf/rdf/badges/gpa.svg)](https://codeclimate.com/github/ruby-rdf/rdf)
1514
[![Coverage Status](https://coveralls.io/repos/ruby-rdf/rdf/badge.svg)](https://coveralls.io/r/ruby-rdf/rdf)
1615
[![Join the chat at https://gitter.im/ruby-rdf/rdf](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ruby-rdf/rdf?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
1716

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
2.1.0
1+
2.1.1

dependencyci.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
platform:
2+
Rubygems:
3+
rdf-isomorphic:
4+
tests:
5+
unmaintained: skip

lib/rdf.rb

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,20 @@ def self.[](property)
206206
property.to_s =~ %r{_\d+} ? RDF::URI("#{to_uri}#{property}") : RDF::RDFV[property]
207207
end
208208

209+
##
210+
# Return an enumerator over {RDF::Statement} defined for this vocabulary.
211+
# @return [RDF::Enumerable::Enumerator]
212+
# @see Object#enum_for
213+
def self.enum_for(method = :each_statement, *args)
214+
# Ensure that enumerators are, themselves, queryable
215+
Enumerable::Enumerator.new do |yielder|
216+
RDF::RDFV.send(method, *args) {|*y| yielder << (y.length > 1 ? y : y.first)}
217+
end
218+
end
219+
class << self
220+
alias_method :to_enum, :enum_for
221+
end
222+
209223
##
210224
# respond to module or RDFV
211225
def self.respond_to?(method, include_all = false)

lib/rdf/cli.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,9 @@ def self.parse(files, options = {}, &block)
439439
# If files are empty, either use options[:execute]
440440
input = options[:evaluate] ? StringIO.new(options[:evaluate]) : $stdin
441441
input.set_encoding(options.fetch(:encoding, Encoding::UTF_8))
442-
RDF::Reader.for(options[:format] || :ntriples).new(input, options) do |reader|
442+
r = RDF::Reader.for(options[:format] || :ntriples)
443+
(@readers ||= []) << r
444+
r.new(input, options) do |reader|
443445
yield(reader)
444446
end
445447
else

lib/rdf/format.rb

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,19 @@ def self.reader_types
207207
reader_symbols.flat_map {|s| RDF::Format.for(s).content_type}.uniq
208208
end
209209

210+
##
211+
# Returns the set of content types with quality for available RDF::Reader subclasses.
212+
#
213+
# @example
214+
#
215+
# accept_types = RDF::Format.accept_types
216+
# # => %w(text/html;q=0.5 text/turtle ...)
217+
#
218+
# @return [Array<String>]
219+
def self.accept_types
220+
reader_symbols.flat_map {|s| RDF::Format.for(s).accept_type}.uniq
221+
end
222+
210223
##
211224
# Returns the set of format symbols for available RDF::Writer subclasses.
212225
#
@@ -400,6 +413,11 @@ class << self
400413
# extensions, that should be mapped to the given MIME type and handled
401414
# by this class.
402415
#
416+
# Optionally, both `type`, `alias`, and `aliases`, may be parameterized
417+
# for expressing quality.
418+
#
419+
# content_type "text/html;q=0.4"
420+
#
403421
# @param [String] type
404422
# @param [Hash{Symbol => Object}] options
405423
# @option options [String] :alias (nil)
@@ -420,10 +438,14 @@ def self.content_type(type = nil, options = {})
420438
[@@content_type[self], @@content_types.map {
421439
|ct, cl| (cl.include?(self) && ct != @@content_type[self]) ? ct : nil }].flatten.compact
422440
else
441+
accept_type, type = type, type.split(';').first
423442
@@content_type[self] = type
424443
@@content_types[type] ||= []
425444
@@content_types[type] << self unless @@content_types[type].include?(self)
426445

446+
@@accept_types[accept_type] ||= []
447+
@@accept_types[accept_type] << self unless @@accept_types[accept_type].include?(self)
448+
427449
if extensions = (options[:extension] || options[:extensions])
428450
extensions = Array(extensions).map(&:to_sym)
429451
extensions.each do |ext|
@@ -433,13 +455,26 @@ def self.content_type(type = nil, options = {})
433455
end
434456
if aliases = (options[:alias] || options[:aliases])
435457
aliases = Array(aliases).each do |a|
436-
@@content_types[a] ||= []
437-
@@content_types[a] << self unless @@content_types[a].include?(self)
458+
aa = a.split(';').first
459+
@@accept_types[a] ||= []
460+
@@accept_types[a] << self unless @@accept_types[a].include?(self)
461+
462+
@@content_types[aa] ||= []
463+
@@content_types[aa] << self unless @@content_types[aa].include?(self)
438464
end
439465
end
440466
end
441467
end
442468

469+
##
470+
# Returns an array of values appropriate for an Accept header.
471+
# Same as `self.content_type`, if no parameter is given when defined.
472+
#
473+
# @return [Array<String>]
474+
def self.accept_type
475+
@@accept_types.map {|t, formats| t if formats.include?(self)}.compact
476+
end
477+
443478
##
444479
# Retrieves or defines file extensions for this RDF serialization format.
445480
#
@@ -488,6 +523,7 @@ def self.content_encoding(encoding = nil)
488523
@@content_type = {} # @private
489524
@@content_types = {} # @private
490525
@@content_encoding = {} # @private
526+
@@accept_types = {} # @private
491527
@@readers = {} # @private
492528
@@writers = {} # @private
493529
@@subclasses = [] # @private

lib/rdf/mixin/enumerator.rb

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,11 @@ class Enumerator < ::Enumerator
77
include Queryable
88
include Enumerable
99

10-
def method_missing(method, *args)
11-
self.to_a if method.to_sym == :to_ary
12-
end
13-
1410
# Make sure returned arrays are also queryable
1511
def to_a
1612
return super.to_a.extend(RDF::Queryable, RDF::Enumerable)
1713
end
14+
alias_method :to_ary, :to_a
1815
end
1916
end
2017

lib/rdf/model/dataset.rb

Lines changed: 100 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,83 @@ module RDF
22
##
33
# An RDF Dataset
44
#
5-
# Datasets are immutable by default. {RDF::Repository} provides an interface
5+
# Datasets are immutable by default. {RDF::Repository} provides an interface
66
# for mutable Datasets.
7-
#
7+
#
8+
# A Dataset functions as an a set of named RDF graphs with a default graph.
9+
# It implements {RDF::Enumerable} and {RDF::Queryable} over the whole set;
10+
# if no specific graph name is queried, enumerating and querying takes place
11+
# over the intersection of all the graphs in the Dataset.
12+
#
13+
# The default graph is named with a constant `DEFAULT_GRAPH`.
14+
#
15+
# @example initializing an RDF::Dataset with existing data
16+
# statements = [RDF::Statement.new(RDF::URI(:s), RDF::URI(:p), :o)]
17+
# dataset = RDF::Dataset.new(statements: statements)
18+
# dataset.count # => 1
19+
#
820
# @see https://www.w3.org/TR/rdf11-concepts/#section-dataset
921
# @see https://www.w3.org/TR/rdf11-datasets/
1022
class Dataset
11-
include RDF::Countable
1223
include RDF::Enumerable
1324
include RDF::Durable
1425
include RDF::Queryable
1526

16-
ISOLATION_LEVELS = [ :read_uncommitted,
17-
:read_committed,
18-
:repeatable_read,
19-
:snapshot,
20-
:serializable].freeze
27+
DEFAULT_GRAPH = false
28+
29+
ISOLATION_LEVELS = [ :read_uncommitted,
30+
:read_committed,
31+
:repeatable_read,
32+
:snapshot,
33+
:serializable ].freeze
34+
35+
##
36+
# @param [RDF::Enumerable, Array<RDF::Statement>] statements the initial
37+
# contents of the dataset
38+
# @yield [dataset] yields itself when a block is given
39+
# @yieldparam [RDF::Dataset] dataset
40+
def initialize(statements: [], **options, &block)
41+
@statements = statements.map do |s|
42+
s = s.dup
43+
s.graph_name ||= DEFAULT_GRAPH
44+
s.freeze
45+
end.freeze
46+
47+
if block_given?
48+
case block.arity
49+
when 1 then yield self
50+
else instance_eval(&block)
51+
end
52+
end
53+
end
54+
55+
##
56+
# @private
57+
# @see RDF::Durable#durable?
58+
def durable?
59+
false
60+
end
61+
62+
##
63+
# @private
64+
# @see RDF::Enumerable#each_statement
65+
def each_statement
66+
if block_given?
67+
@statements.each do |st|
68+
if st.graph_name.equal?(DEFAULT_GRAPH)
69+
st = st.dup
70+
st.graph_name = nil
71+
end
72+
73+
yield st
74+
end
75+
76+
self
77+
end
78+
79+
enum_statement
80+
end
81+
alias_method :each, :each_statement
2182

2283
##
2384
# Returns a developer-friendly representation of this object.
@@ -36,13 +97,42 @@ def inspect!
3697
each_statement { |statement| statement.inspect! }
3798
nil
3899
end
39-
100+
40101
##
41102
# @return [Symbol] a representation of the isolation level for reads of this
42-
# Dataset. One of `:read_uncommitted`, `:read_committed`, `:repeatable_read`,
103+
# Dataset. One of `:read_uncommitted`, `:read_committed`, `:repeatable_read`,
43104
# `:snapshot`, or `:serializable`.
44105
def isolation_level
45106
:read_committed
46107
end
108+
109+
##
110+
# @private
111+
# @see RDF::Enumerable#supports?
112+
def supports?(feature)
113+
return true if feature == :graph_name
114+
super
115+
end
116+
117+
protected
118+
119+
##
120+
# Implements basic query pattern matching over the Dataset, with handling
121+
# for a default graph.
122+
def query_pattern(pattern, options = {}, &block)
123+
return super unless pattern.graph_name == DEFAULT_GRAPH
124+
125+
if block_given?
126+
pattern = pattern.dup
127+
pattern.graph_name = nil
128+
129+
each_statement do |statement|
130+
yield statement if (statement.graph_name == DEFAULT_GRAPH ||
131+
statement.graph_name.nil?) && pattern === statement
132+
end
133+
else
134+
enum_for(:query_pattern, pattern, options)
135+
end
136+
end
47137
end
48138
end

lib/rdf/model/literal.rb

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,6 +408,30 @@ def canonicalize!
408408
self
409409
end
410410

411+
##
412+
# Returns the literal, first removing all whitespace on both ends of the value, and then changing remaining consecutive whitespace groups into one space each.
413+
#
414+
# Note that it handles both ASCII and Unicode whitespace.
415+
#
416+
# @see [String#squish](http://apidock.com/rails/String/squish)
417+
# @return [RDF::Literal] a new literal based on `self`.
418+
def squish(*other_string)
419+
self.dup.squish!
420+
end
421+
422+
##
423+
# Performs a destructive {#squish}.
424+
#
425+
# @see [String#squish!](http://apidock.com/rails/String/squish%21)
426+
# @return self
427+
def squish!
428+
@string = value.
429+
gsub(/\A[[:space:]]+/, '').
430+
gsub(/[[:space:]]+\z/, '').
431+
gsub(/[[:space:]]+/, ' ')
432+
self
433+
end
434+
411435
##
412436
# Escape a literal using ECHAR escapes.
413437
#

lib/rdf/model/literal/double.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ module RDF; class Literal
1212
# @since 0.2.1
1313
class Double < Numeric
1414
DATATYPE = RDF::XSD.double
15-
GRAMMAR = /^(?:NaN|(?:[\+\-]?(?:INF|(?:\d+(\.\d*)?([eE][\+\-]?\d+)?))))$/.freeze
15+
GRAMMAR = /^(?:NaN|(?:[\+\-]?(?:INF|(?:\d+(\.\d*)?(e[\+\-]?\d+)?))))$/i.freeze
1616

1717
##
1818
# @param [Float, #to_f] value

lib/rdf/model/literal/integer.rb

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,8 @@ def initialize(value, options = {})
2323
@string = options[:lexical] if options.has_key?(:lexical)
2424
@string ||= value if value.is_a?(String)
2525
@object = case
26-
when value.is_a?(::String) then Integer(value) rescue nil
27-
when value.is_a?(::Integer) then value
2826
when value.respond_to?(:to_i) then value.to_i
27+
when value.is_a?(::Integer) then value
2928
else Integer(value.to_s) rescue nil
3029
end
3130
end

0 commit comments

Comments
 (0)