openlogic-rdf 0.3.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.
- data/AUTHORS +3 -0
- data/CREDITS +9 -0
- data/README +361 -0
- data/UNLICENSE +24 -0
- data/VERSION +1 -0
- data/bin/rdf +18 -0
- data/etc/doap.nt +62 -0
- data/lib/df.rb +1 -0
- data/lib/rdf/cli.rb +200 -0
- data/lib/rdf/format.rb +383 -0
- data/lib/rdf/mixin/countable.rb +39 -0
- data/lib/rdf/mixin/durable.rb +31 -0
- data/lib/rdf/mixin/enumerable.rb +637 -0
- data/lib/rdf/mixin/indexable.rb +26 -0
- data/lib/rdf/mixin/inferable.rb +5 -0
- data/lib/rdf/mixin/mutable.rb +191 -0
- data/lib/rdf/mixin/queryable.rb +265 -0
- data/lib/rdf/mixin/readable.rb +15 -0
- data/lib/rdf/mixin/type_check.rb +21 -0
- data/lib/rdf/mixin/writable.rb +152 -0
- data/lib/rdf/model/graph.rb +263 -0
- data/lib/rdf/model/list.rb +731 -0
- data/lib/rdf/model/literal/boolean.rb +121 -0
- data/lib/rdf/model/literal/date.rb +73 -0
- data/lib/rdf/model/literal/datetime.rb +72 -0
- data/lib/rdf/model/literal/decimal.rb +86 -0
- data/lib/rdf/model/literal/double.rb +189 -0
- data/lib/rdf/model/literal/integer.rb +126 -0
- data/lib/rdf/model/literal/numeric.rb +184 -0
- data/lib/rdf/model/literal/time.rb +87 -0
- data/lib/rdf/model/literal/token.rb +47 -0
- data/lib/rdf/model/literal/xml.rb +39 -0
- data/lib/rdf/model/literal.rb +373 -0
- data/lib/rdf/model/node.rb +156 -0
- data/lib/rdf/model/resource.rb +28 -0
- data/lib/rdf/model/statement.rb +296 -0
- data/lib/rdf/model/term.rb +77 -0
- data/lib/rdf/model/uri.rb +570 -0
- data/lib/rdf/model/value.rb +133 -0
- data/lib/rdf/nquads.rb +152 -0
- data/lib/rdf/ntriples/format.rb +48 -0
- data/lib/rdf/ntriples/reader.rb +239 -0
- data/lib/rdf/ntriples/writer.rb +219 -0
- data/lib/rdf/ntriples.rb +104 -0
- data/lib/rdf/query/pattern.rb +329 -0
- data/lib/rdf/query/solution.rb +252 -0
- data/lib/rdf/query/solutions.rb +237 -0
- data/lib/rdf/query/variable.rb +221 -0
- data/lib/rdf/query.rb +404 -0
- data/lib/rdf/reader.rb +511 -0
- data/lib/rdf/repository.rb +389 -0
- data/lib/rdf/transaction.rb +161 -0
- data/lib/rdf/util/aliasing.rb +63 -0
- data/lib/rdf/util/cache.rb +139 -0
- data/lib/rdf/util/file.rb +38 -0
- data/lib/rdf/util/uuid.rb +36 -0
- data/lib/rdf/util.rb +6 -0
- data/lib/rdf/version.rb +19 -0
- data/lib/rdf/vocab/cc.rb +18 -0
- data/lib/rdf/vocab/cert.rb +13 -0
- data/lib/rdf/vocab/dc.rb +63 -0
- data/lib/rdf/vocab/dc11.rb +23 -0
- data/lib/rdf/vocab/doap.rb +45 -0
- data/lib/rdf/vocab/exif.rb +168 -0
- data/lib/rdf/vocab/foaf.rb +69 -0
- data/lib/rdf/vocab/geo.rb +13 -0
- data/lib/rdf/vocab/http.rb +26 -0
- data/lib/rdf/vocab/owl.rb +59 -0
- data/lib/rdf/vocab/rdfs.rb +17 -0
- data/lib/rdf/vocab/rsa.rb +12 -0
- data/lib/rdf/vocab/rss.rb +14 -0
- data/lib/rdf/vocab/sioc.rb +93 -0
- data/lib/rdf/vocab/skos.rb +36 -0
- data/lib/rdf/vocab/wot.rb +21 -0
- data/lib/rdf/vocab/xhtml.rb +9 -0
- data/lib/rdf/vocab/xsd.rb +58 -0
- data/lib/rdf/vocab.rb +215 -0
- data/lib/rdf/writer.rb +475 -0
- data/lib/rdf.rb +192 -0
- metadata +173 -0
@@ -0,0 +1,191 @@
|
|
1
|
+
module RDF
|
2
|
+
##
|
3
|
+
# Classes that include this module must implement the methods
|
4
|
+
# `#insert_statement`, `#delete_statement` and `#each_statement`.
|
5
|
+
#
|
6
|
+
# @see RDF::Graph
|
7
|
+
# @see RDF::Repository
|
8
|
+
module Mutable
|
9
|
+
extend RDF::Util::Aliasing::LateBound
|
10
|
+
include RDF::Readable
|
11
|
+
include RDF::Writable
|
12
|
+
|
13
|
+
##
|
14
|
+
# Returns `true` if `self` is mutable.
|
15
|
+
#
|
16
|
+
# @return [Boolean]
|
17
|
+
# @see #immutable?
|
18
|
+
def mutable?
|
19
|
+
writable?
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Returns `true` if `self` is immutable.
|
24
|
+
#
|
25
|
+
# @return [Boolean]
|
26
|
+
# @see #mutable?
|
27
|
+
def immutable?
|
28
|
+
!mutable?
|
29
|
+
end
|
30
|
+
|
31
|
+
##
|
32
|
+
# Loads RDF statements from the given file or URL into `self`.
|
33
|
+
#
|
34
|
+
# @param [String, #to_s] filename
|
35
|
+
# @param [Hash{Symbol => Object}] options
|
36
|
+
# @return [void]
|
37
|
+
def load(filename, options = {})
|
38
|
+
raise TypeError.new("#{self} is immutable") if immutable?
|
39
|
+
|
40
|
+
Reader.open(filename, {:base_uri => filename}.merge(options)) do |reader|
|
41
|
+
if options[:context]
|
42
|
+
statements = []
|
43
|
+
reader.each_statement do |statement|
|
44
|
+
statement.context = options[:context]
|
45
|
+
statements << statement
|
46
|
+
end
|
47
|
+
insert_statements(statements)
|
48
|
+
statements.size
|
49
|
+
else
|
50
|
+
insert_statements(reader)
|
51
|
+
nil
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
alias_method :load!, :load
|
57
|
+
|
58
|
+
##
|
59
|
+
# Inserts RDF data into `self`.
|
60
|
+
#
|
61
|
+
# @param [RDF::Enumerable, RDF::Statement, #to_rdf] data
|
62
|
+
# @raise [TypeError] if `self` is immutable
|
63
|
+
# @return [Mutable]
|
64
|
+
# @see RDF::Writable#<<
|
65
|
+
def <<(data)
|
66
|
+
raise TypeError.new("#{self} is immutable") if immutable?
|
67
|
+
|
68
|
+
super # RDF::Writable#<<
|
69
|
+
end
|
70
|
+
|
71
|
+
##
|
72
|
+
# Inserts RDF statements into `self`.
|
73
|
+
#
|
74
|
+
# @param [Array<RDF::Statement>] statements
|
75
|
+
# @raise [TypeError] if `self` is immutable
|
76
|
+
# @return [Mutable]
|
77
|
+
# @see RDF::Writable#insert
|
78
|
+
def insert(*statements)
|
79
|
+
raise TypeError.new("#{self} is immutable") if immutable?
|
80
|
+
|
81
|
+
super # RDF::Writable#insert
|
82
|
+
end
|
83
|
+
|
84
|
+
##
|
85
|
+
# Updates RDF statements in `self`.
|
86
|
+
#
|
87
|
+
# `#update([subject, predicate, object])` is equivalent to
|
88
|
+
# `#delete([subject, predicate, nil])` followed by
|
89
|
+
# `#insert([subject, predicate, object])` unless `object` is `nil`.
|
90
|
+
#
|
91
|
+
# @param [Enumerable<RDF::Statement>] statements
|
92
|
+
# @raise [TypeError] if `self` is immutable
|
93
|
+
# @return [Mutable]
|
94
|
+
def update(*statements)
|
95
|
+
raise TypeError.new("#{self} is immutable") if immutable?
|
96
|
+
|
97
|
+
statements.each do |statement|
|
98
|
+
if (statement = Statement.from(statement))
|
99
|
+
delete([statement.subject, statement.predicate, nil])
|
100
|
+
insert(statement) if statement.has_object?
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
alias_method :update!, :update
|
106
|
+
|
107
|
+
##
|
108
|
+
# Deletes RDF statements from `self`.
|
109
|
+
#
|
110
|
+
# @param [Enumerable<RDF::Statement>] statements
|
111
|
+
# @raise [TypeError] if `self` is immutable
|
112
|
+
# @return [Mutable]
|
113
|
+
def delete(*statements)
|
114
|
+
raise TypeError.new("#{self} is immutable") if immutable?
|
115
|
+
|
116
|
+
statements.map! do |value|
|
117
|
+
case
|
118
|
+
when value.respond_to?(:each_statement)
|
119
|
+
delete_statements(value)
|
120
|
+
nil
|
121
|
+
when (statement = Statement.from(value)).valid?
|
122
|
+
statement
|
123
|
+
else
|
124
|
+
delete_statements(query(value))
|
125
|
+
nil
|
126
|
+
end
|
127
|
+
end
|
128
|
+
statements.compact!
|
129
|
+
delete_statements(statements) unless statements.empty?
|
130
|
+
|
131
|
+
return self
|
132
|
+
end
|
133
|
+
|
134
|
+
alias_method :delete!, :delete
|
135
|
+
|
136
|
+
##
|
137
|
+
# Deletes all RDF statements from `self`.
|
138
|
+
#
|
139
|
+
# @raise [TypeError] if `self` is immutable
|
140
|
+
# @return [Mutable]
|
141
|
+
def clear
|
142
|
+
raise TypeError.new("#{self} is immutable") if immutable?
|
143
|
+
|
144
|
+
if respond_to?(:clear_statements)
|
145
|
+
clear_statements
|
146
|
+
else
|
147
|
+
delete_statements(self)
|
148
|
+
end
|
149
|
+
|
150
|
+
return self
|
151
|
+
end
|
152
|
+
|
153
|
+
alias_method :clear!, :clear
|
154
|
+
|
155
|
+
protected
|
156
|
+
|
157
|
+
##
|
158
|
+
# Deletes the given RDF statements from the underlying storage.
|
159
|
+
#
|
160
|
+
# Defaults to invoking {#delete_statement} for each given statement.
|
161
|
+
#
|
162
|
+
# Subclasses of {RDF::Repository} may wish to override this method if
|
163
|
+
# they are capable of more efficiently deleting multiple statements at
|
164
|
+
# once.
|
165
|
+
#
|
166
|
+
# @param [RDF::Enumerable] statements
|
167
|
+
# @return [void]
|
168
|
+
def delete_statements(statements)
|
169
|
+
each = statements.respond_to?(:each_statement) ? :each_statement : :each
|
170
|
+
statements.__send__(each) do |statement|
|
171
|
+
delete_statement(statement)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
##
|
176
|
+
# Deletes an RDF statement from the underlying storage.
|
177
|
+
#
|
178
|
+
# Subclasses of {RDF::Repository} must implement this method, except if
|
179
|
+
# they are immutable.
|
180
|
+
#
|
181
|
+
# @param [RDF::Statement] statement
|
182
|
+
# @return [void]
|
183
|
+
# @abstract
|
184
|
+
def delete_statement(statement)
|
185
|
+
raise NotImplementedError.new("#{self.class}#delete_statement")
|
186
|
+
end
|
187
|
+
|
188
|
+
protected :delete_statements
|
189
|
+
protected :delete_statement
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
module RDF
|
2
|
+
##
|
3
|
+
# An RDF query mixin.
|
4
|
+
#
|
5
|
+
# Classes that include this module should implement a `#query_pattern` method that
|
6
|
+
# yields {RDF::Statement RDF statements}. Classes may also implement an optimized
|
7
|
+
# `#query_execute` method that yields {RDF::Statement RDF statements}.
|
8
|
+
#
|
9
|
+
# @see RDF::Graph
|
10
|
+
# @see RDF::Repository
|
11
|
+
module Queryable
|
12
|
+
include ::Enumerable
|
13
|
+
|
14
|
+
##
|
15
|
+
# Queries `self` for RDF statements matching the given `pattern`.
|
16
|
+
#
|
17
|
+
# This method delegates to the protected {#query_pattern} method for the
|
18
|
+
# actual lower-level query pattern matching implementation.
|
19
|
+
#
|
20
|
+
# @example
|
21
|
+
# queryable.query([nil, RDF::DOAP.developer, nil])
|
22
|
+
# queryable.query(:predicate => RDF::DOAP.developer)
|
23
|
+
#
|
24
|
+
# @param [RDF::Query, RDF::Statement, Array(RDF::Term), Hash] pattern
|
25
|
+
# @yield [statement]
|
26
|
+
# each matching statement
|
27
|
+
# @yieldparam [RDF::Statement] statement
|
28
|
+
# @yieldreturn [void] ignored
|
29
|
+
# @return [Enumerator]
|
30
|
+
# @see RDF::Queryable#query_pattern
|
31
|
+
def query(pattern, &block)
|
32
|
+
raise TypeError, "#{self} is not readable" if respond_to?(:readable?) && !readable?
|
33
|
+
|
34
|
+
case pattern
|
35
|
+
# A basic graph pattern (BGP) query:
|
36
|
+
when Query
|
37
|
+
if block_given?
|
38
|
+
before_query(pattern) if respond_to?(:before_query)
|
39
|
+
query_execute(pattern, &block)
|
40
|
+
after_query(pattern) if respond_to?(:after_query)
|
41
|
+
end
|
42
|
+
enum_for(:query_execute, pattern)
|
43
|
+
|
44
|
+
# A simple triple/quad pattern query:
|
45
|
+
else
|
46
|
+
pattern = Query::Pattern.from(pattern)
|
47
|
+
before_query(pattern) if block_given? && respond_to?(:before_query)
|
48
|
+
enum = case
|
49
|
+
# Blank triple/quad patterns are equivalent to iterating over
|
50
|
+
# every statement, so as a minor optimization we'll just do that
|
51
|
+
# directly instead of bothering with `#query_pattern`:
|
52
|
+
when pattern.blank?
|
53
|
+
each(&block) if block_given?
|
54
|
+
enum_for(:each)
|
55
|
+
|
56
|
+
# Constant triple/quad patterns are equivalent to looking up a
|
57
|
+
# particular statement, so as a minor optimization we'll just do
|
58
|
+
# that directly instead of bothering with `#query_pattern`:
|
59
|
+
when pattern.constant?
|
60
|
+
statement = Statement.from(pattern)
|
61
|
+
block.call(statement) if block_given? && include?(statement)
|
62
|
+
enum_for(:query, pattern)
|
63
|
+
|
64
|
+
# Otherwise, we delegate to `#query_pattern`:
|
65
|
+
else # pattern.variable?
|
66
|
+
query_pattern(pattern, &block) if block_given?
|
67
|
+
enum_for(:query_pattern, pattern)
|
68
|
+
end
|
69
|
+
after_query(pattern) if block_given? && respond_to?(:after_query)
|
70
|
+
enum.extend(RDF::Queryable, RDF::Enumerable, RDF::Countable)
|
71
|
+
def enum.to_a
|
72
|
+
super.extend(RDF::Queryable, RDF::Enumerable, RDF::Countable)
|
73
|
+
end
|
74
|
+
enum
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# Queries `self` using the given basic graph pattern (BGP) query,
|
80
|
+
# yielding each matched solution to the given block.
|
81
|
+
#
|
82
|
+
# Since RDF.rb 0.3.0, repository implementations can override this
|
83
|
+
# method in order to provide for storage-specific optimized graph
|
84
|
+
# pattern query execution.
|
85
|
+
#
|
86
|
+
# @param [RDF::Query] query
|
87
|
+
# the query to execute
|
88
|
+
# @yield [solution]
|
89
|
+
# @yieldparam [RDF::Query::Solution] solution
|
90
|
+
# @yieldreturn [void] ignored
|
91
|
+
# @return [void] ignored
|
92
|
+
# @see RDF::Queryable#query
|
93
|
+
# @see RDF::Query#execute
|
94
|
+
# @since 0.3.0
|
95
|
+
def query_execute(query, &block)
|
96
|
+
# By default, we let RDF.rb's built-in `RDF::Query#execute` handle BGP
|
97
|
+
# query execution by breaking down the query into its constituent
|
98
|
+
# triple patterns and invoking `RDF::Query::Pattern#execute` on each
|
99
|
+
# pattern.
|
100
|
+
query.execute(self).each(&block)
|
101
|
+
end
|
102
|
+
protected :query_execute
|
103
|
+
|
104
|
+
##
|
105
|
+
# Queries `self` for RDF statements matching the given `pattern`,
|
106
|
+
# yielding each matched statement to the given block.
|
107
|
+
#
|
108
|
+
# Since RDF.rb 0.2.0, repository implementations should override this
|
109
|
+
# method in order to provide for storage-specific optimized triple
|
110
|
+
# pattern matching.
|
111
|
+
#
|
112
|
+
# @param [RDF::Query::Pattern] pattern
|
113
|
+
# the query pattern to match
|
114
|
+
# @yield [statement]
|
115
|
+
# @yieldparam [RDF::Statement] statement
|
116
|
+
# @yieldreturn [void] ignored
|
117
|
+
# @return [void] ignored
|
118
|
+
# @see RDF::Queryable#query
|
119
|
+
# @see RDF::Query::Pattern#execute
|
120
|
+
# @since 0.2.0
|
121
|
+
def query_pattern(pattern, &block)
|
122
|
+
# By default, we let Ruby's built-in `Enumerable#grep` handle the
|
123
|
+
# matching of statements by iterating over all statements and calling
|
124
|
+
# `RDF::Query::Pattern#===` on each statement.
|
125
|
+
# @see http://ruby-doc.org/core/classes/Enumerable.html#M003121
|
126
|
+
grep(pattern, &block)
|
127
|
+
end
|
128
|
+
protected :query_pattern
|
129
|
+
|
130
|
+
##
|
131
|
+
# Queries `self` for an RDF statement matching the given `pattern` and
|
132
|
+
# returns that statement if found.
|
133
|
+
#
|
134
|
+
# Returns `nil` if no statements match `pattern`.
|
135
|
+
#
|
136
|
+
# @overload first
|
137
|
+
# @return [RDF::Statement]
|
138
|
+
#
|
139
|
+
# @overload first(pattern)
|
140
|
+
# @param [RDF::Query, RDF::Statement, Array(RDF::Term), Hash] pattern
|
141
|
+
# @return [RDF::Statement]
|
142
|
+
#
|
143
|
+
# @return [RDF::Statement]
|
144
|
+
# @since 0.1.9
|
145
|
+
def first(pattern = nil)
|
146
|
+
if pattern
|
147
|
+
query(pattern) do |statement|
|
148
|
+
return statement
|
149
|
+
end
|
150
|
+
return nil
|
151
|
+
else
|
152
|
+
super()
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
##
|
157
|
+
# Queries `self` for an RDF statement matching the given `pattern` and
|
158
|
+
# returns the statement's subject term.
|
159
|
+
#
|
160
|
+
# Returns `nil` if no statements match `pattern`.
|
161
|
+
#
|
162
|
+
# @overload first_subject
|
163
|
+
# @return [RDF::Resource]
|
164
|
+
#
|
165
|
+
# @overload first_subject(pattern)
|
166
|
+
# @param [RDF::Query, RDF::Statement, Array(RDF::Term), Hash] pattern
|
167
|
+
# @return [RDF::Resource]
|
168
|
+
#
|
169
|
+
# @return [RDF::Resource]
|
170
|
+
# @since 0.1.9
|
171
|
+
def first_subject(pattern = nil)
|
172
|
+
__send__(*(pattern ? [:query, pattern] : [:each])) do |statement|
|
173
|
+
return statement.subject
|
174
|
+
end
|
175
|
+
return nil
|
176
|
+
end
|
177
|
+
|
178
|
+
##
|
179
|
+
# Queries `self` for an RDF statement matching the given `pattern` and
|
180
|
+
# returns the statement's predicate term.
|
181
|
+
#
|
182
|
+
# Returns `nil` if no statements match `pattern`.
|
183
|
+
#
|
184
|
+
# @overload first_predicate
|
185
|
+
# @return [RDF::URI]
|
186
|
+
#
|
187
|
+
# @overload first_predicate(pattern)
|
188
|
+
# @param [RDF::Query, RDF::Statement, Array(RDF::Term), Hash] pattern
|
189
|
+
# @return [RDF::URI]
|
190
|
+
#
|
191
|
+
# @return [RDF::URI]
|
192
|
+
# @since 0.1.9
|
193
|
+
def first_predicate(pattern = nil)
|
194
|
+
__send__(*(pattern ? [:query, pattern] : [:each])) do |statement|
|
195
|
+
return statement.predicate
|
196
|
+
end
|
197
|
+
return nil
|
198
|
+
end
|
199
|
+
|
200
|
+
##
|
201
|
+
# Queries `self` for an RDF statement matching the given `pattern` and
|
202
|
+
# returns the statement's object term.
|
203
|
+
#
|
204
|
+
# Returns `nil` if no statements match `pattern`.
|
205
|
+
#
|
206
|
+
# @overload first_object
|
207
|
+
# @return [RDF::Term]
|
208
|
+
#
|
209
|
+
# @overload first_object(pattern)
|
210
|
+
# @param [RDF::Query, RDF::Statement, Array(RDF::Term), Hash] pattern
|
211
|
+
# @return [RDF::Term]
|
212
|
+
#
|
213
|
+
# @return [RDF::Term]
|
214
|
+
# @since 0.1.9
|
215
|
+
def first_object(pattern = nil)
|
216
|
+
__send__(*(pattern ? [:query, pattern] : [:each])) do |statement|
|
217
|
+
return statement.object
|
218
|
+
end
|
219
|
+
return nil
|
220
|
+
end
|
221
|
+
|
222
|
+
##
|
223
|
+
# Queries `self` for RDF statements matching the given `pattern` and
|
224
|
+
# returns the first found object literal.
|
225
|
+
#
|
226
|
+
# Returns `nil` if no statements match `pattern` or if none of the found
|
227
|
+
# statements have a literal as their object term.
|
228
|
+
#
|
229
|
+
# @overload first_literal
|
230
|
+
# @return [RDF::Literal]
|
231
|
+
#
|
232
|
+
# @overload first_literal(pattern)
|
233
|
+
# @param [RDF::Query, RDF::Statement, Array(RDF::Term), Hash] pattern
|
234
|
+
# @return [RDF::Literal]
|
235
|
+
#
|
236
|
+
# @return [RDF::Literal]
|
237
|
+
# @since 0.1.9
|
238
|
+
def first_literal(pattern = nil)
|
239
|
+
__send__(*(pattern ? [:query, pattern] : [:each])) do |statement|
|
240
|
+
return statement.object if statement.object.is_a?(RDF::Literal)
|
241
|
+
end
|
242
|
+
return nil
|
243
|
+
end
|
244
|
+
|
245
|
+
##
|
246
|
+
# Queries `self` for RDF statements matching the given `pattern` and
|
247
|
+
# returns the value of the first found object literal.
|
248
|
+
#
|
249
|
+
# Returns `nil` if no statements match `pattern` or if none of the found
|
250
|
+
# statements have a literal as their object term.
|
251
|
+
#
|
252
|
+
# @overload first_value
|
253
|
+
# @return [Object]
|
254
|
+
#
|
255
|
+
# @overload first_value(pattern)
|
256
|
+
# @param [RDF::Query, RDF::Statement, Array(RDF::Term), Hash] pattern
|
257
|
+
# @return [Object]
|
258
|
+
#
|
259
|
+
# @return [Object]
|
260
|
+
# @since 0.1.9
|
261
|
+
def first_value(pattern = nil)
|
262
|
+
(literal = first_literal(pattern)) ? literal.value : nil
|
263
|
+
end
|
264
|
+
end # Queryable
|
265
|
+
end # RDF
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module RDF
|
2
|
+
##
|
3
|
+
# An RDF type check mixin.
|
4
|
+
#
|
5
|
+
# This module implements #raise_error, which will raise TypeError.
|
6
|
+
#
|
7
|
+
# @see RDF::Value
|
8
|
+
# @see RDF::Literal
|
9
|
+
# @see RDF::Literal
|
10
|
+
module TypeCheck
|
11
|
+
##
|
12
|
+
# Default implementation of type_error, which returns false.
|
13
|
+
# Classes including RDF::TypeCheck will raise TypeError
|
14
|
+
# instead.
|
15
|
+
#
|
16
|
+
# @raise [TypeError]
|
17
|
+
def type_error(message)
|
18
|
+
raise TypeError, message
|
19
|
+
end
|
20
|
+
end # TypeCheck
|
21
|
+
end # RDF
|
@@ -0,0 +1,152 @@
|
|
1
|
+
module RDF
|
2
|
+
##
|
3
|
+
# Classes that include this module must implement the methods
|
4
|
+
# `#insert_statement`.
|
5
|
+
#
|
6
|
+
# @see RDF::Graph
|
7
|
+
# @see RDF::Repository
|
8
|
+
module Writable
|
9
|
+
extend RDF::Util::Aliasing::LateBound
|
10
|
+
|
11
|
+
##
|
12
|
+
# Returns `true` if `self` is writable.
|
13
|
+
#
|
14
|
+
# @return [Boolean] `true` or `false`
|
15
|
+
# @see RDF::Readable#readable?
|
16
|
+
def writable?
|
17
|
+
true
|
18
|
+
end
|
19
|
+
|
20
|
+
##
|
21
|
+
# Inserts RDF data into `self`.
|
22
|
+
#
|
23
|
+
# @param [RDF::Enumerable, RDF::Statement, #to_rdf] data
|
24
|
+
# @return [RDF::Writable] `self`
|
25
|
+
def <<(data)
|
26
|
+
case data
|
27
|
+
when RDF::Reader
|
28
|
+
insert_reader(data)
|
29
|
+
when RDF::Graph
|
30
|
+
insert_graph(data)
|
31
|
+
when RDF::Enumerable
|
32
|
+
insert_statements(data)
|
33
|
+
when RDF::Statement
|
34
|
+
insert_statement(data)
|
35
|
+
else case
|
36
|
+
when data.respond_to?(:to_rdf) && !data.equal?(rdf = data.to_rdf)
|
37
|
+
self << rdf
|
38
|
+
else
|
39
|
+
insert_statement(Statement.from(data))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
return self
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Inserts RDF statements into `self`.
|
48
|
+
#
|
49
|
+
# @param [Array<RDF::Statement>] statements
|
50
|
+
# @return [RDF::Writable] `self`
|
51
|
+
def insert(*statements)
|
52
|
+
statements.map! do |value|
|
53
|
+
case
|
54
|
+
when value.respond_to?(:each_statement)
|
55
|
+
insert_statements(value)
|
56
|
+
nil
|
57
|
+
when (statement = Statement.from(value)).valid?
|
58
|
+
statement
|
59
|
+
else
|
60
|
+
raise ArgumentError.new("not a valid statement: #{value.inspect}")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
statements.compact!
|
64
|
+
insert_statements(statements) unless statements.empty?
|
65
|
+
|
66
|
+
return self
|
67
|
+
end
|
68
|
+
alias_method :insert!, :insert
|
69
|
+
|
70
|
+
protected
|
71
|
+
|
72
|
+
##
|
73
|
+
# Inserts statements from the given RDF reader into the underlying
|
74
|
+
# storage or output stream.
|
75
|
+
#
|
76
|
+
# Defaults to passing the reader to the {#insert_statements} method.
|
77
|
+
#
|
78
|
+
# Subclasses of {RDF::Repository} may wish to override this method in
|
79
|
+
# case their underlying storage can efficiently import RDF data directly
|
80
|
+
# in particular serialization formats, thus avoiding the intermediate
|
81
|
+
# parsing overhead.
|
82
|
+
#
|
83
|
+
# @param [RDF::Reader] reader
|
84
|
+
# @return [void]
|
85
|
+
# @since 0.2.3
|
86
|
+
def insert_reader(reader)
|
87
|
+
insert_statements(reader)
|
88
|
+
end
|
89
|
+
|
90
|
+
##
|
91
|
+
# Inserts the given RDF graph into the underlying storage or output
|
92
|
+
# stream.
|
93
|
+
#
|
94
|
+
# Defaults to passing the graph to the {#insert_statements} method.
|
95
|
+
#
|
96
|
+
# Subclasses of {RDF::Repository} may wish to override this method in
|
97
|
+
# case their underlying storage architecture is graph-centric rather
|
98
|
+
# than statement-oriented.
|
99
|
+
#
|
100
|
+
# Subclasses of {RDF::Writer} may wish to override this method if the
|
101
|
+
# output format they implement supports named graphs, in which case
|
102
|
+
# implementing this method may help in producing prettier and more
|
103
|
+
# concise output.
|
104
|
+
#
|
105
|
+
# @param [RDF::Graph] graph
|
106
|
+
# @return [void]
|
107
|
+
def insert_graph(graph)
|
108
|
+
insert_statements(graph)
|
109
|
+
end
|
110
|
+
|
111
|
+
##
|
112
|
+
# Inserts the given RDF statements into the underlying storage or output
|
113
|
+
# stream.
|
114
|
+
#
|
115
|
+
# Defaults to invoking {#insert_statement} for each given statement.
|
116
|
+
#
|
117
|
+
# Subclasses of {RDF::Repository} may wish to override this method if
|
118
|
+
# they are capable of more efficiently inserting multiple statements at
|
119
|
+
# once.
|
120
|
+
#
|
121
|
+
# Subclasses of {RDF::Writer} don't generally need to implement this
|
122
|
+
# method.
|
123
|
+
#
|
124
|
+
# @param [RDF::Enumerable] statements
|
125
|
+
# @return [void]
|
126
|
+
# @since 0.1.6
|
127
|
+
def insert_statements(statements)
|
128
|
+
each = statements.respond_to?(:each_statement) ? :each_statement : :each
|
129
|
+
statements.__send__(each) do |statement|
|
130
|
+
insert_statement(statement)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
##
|
135
|
+
# Inserts an RDF statement into the underlying storage or output stream.
|
136
|
+
#
|
137
|
+
# Subclasses of {RDF::Repository} must implement this method, except if
|
138
|
+
# they are immutable.
|
139
|
+
#
|
140
|
+
# Subclasses of {RDF::Writer} must implement this method.
|
141
|
+
#
|
142
|
+
# @param [RDF::Statement] statement
|
143
|
+
# @return [void]
|
144
|
+
# @abstract
|
145
|
+
def insert_statement(statement)
|
146
|
+
raise NotImplementedError.new("#{self.class}#insert_statement")
|
147
|
+
end
|
148
|
+
|
149
|
+
protected :insert_statements
|
150
|
+
protected :insert_statement
|
151
|
+
end # Writable
|
152
|
+
end # RDF
|