rdf 3.1.7 → 3.1.12

Sign up to get free protection for your applications and to get access to all the features.
@@ -122,7 +122,7 @@ module RDF
122
122
 
123
123
  statements.each do |statement|
124
124
  if (statement = Statement.from(statement))
125
- if statement.has_object?
125
+ if statement.object?
126
126
  delete_insert([[statement.subject, statement.predicate, nil]], [statement])
127
127
  else
128
128
  delete([statement.subject, statement.predicate, nil])
@@ -104,7 +104,7 @@ module RDF
104
104
  # @private
105
105
  # @see RDF::Enumerable#supports?
106
106
  def supports?(feature)
107
- return true if [:graph_name, :rdfstar].include?(feature)
107
+ return true if %i(graph_name rdfstar).include?(feature)
108
108
  super
109
109
  end
110
110
 
@@ -138,11 +138,22 @@ module RDF
138
138
  end
139
139
 
140
140
  ##
141
- # Returns `true` to indicate that this is a graph.
141
+ # @overload graph?
142
+ # Returns `true` to indicate that this is a graph.
142
143
  #
143
- # @return [Boolean]
144
- def graph?
145
- true
144
+ # @return [Boolean]
145
+ # @overload graph?(name)
146
+ # Returns `true` if `self` contains the given RDF graph_name.
147
+ #
148
+ # @param [RDF::Resource, false] graph_name
149
+ # Use value `false` to query for the default graph_name
150
+ # @return [Boolean]
151
+ def graph?(*args)
152
+ case args.length
153
+ when 0 then true
154
+ when 1 then graph_name == args.first
155
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
156
+ end
146
157
  end
147
158
 
148
159
  ##
@@ -215,18 +226,29 @@ module RDF
215
226
  end
216
227
 
217
228
  ##
218
- # Returns `true` if this graph contains the given RDF statement.
229
+ # @overload statement?
230
+ # Returns `false` indicating this is not an RDF::Statemenet.
231
+ # @see RDF::Value#statement?
232
+ # @return [Boolean]
233
+ # @overload statement?(statement)
234
+ # Returns `true` if this graph contains the given RDF statement.
219
235
  #
220
- # A statement is in a graph if the statement if it has the same triples without regard to graph_name.
236
+ # A statement is in a graph if the statement if it has the same triples without regard to graph_name.
221
237
  #
222
- # @param [Statement] statement
223
- # @return [Boolean]
224
- # @see RDF::Enumerable#has_statement?
225
- def has_statement?(statement)
226
- statement = statement.dup
227
- statement.graph_name = graph_name
228
- @data.has_statement?(statement)
238
+ # @param [Statement] statement
239
+ # @return [Boolean]
240
+ # @see RDF::Enumerable#statement?
241
+ def statement?(*args)
242
+ case args.length
243
+ when 0 then false
244
+ when 1
245
+ statement = args.first.dup
246
+ statement.graph_name = graph_name
247
+ @data.statement?(statement)
248
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
249
+ end
229
250
  end
251
+ alias_method :has_statement?, :statement?
230
252
 
231
253
  ##
232
254
  # Enumerates each RDF statement in this graph.
@@ -49,14 +49,23 @@ module RDF
49
49
  # g = RDF::Graph.new << l
50
50
  # g.count # => l.count
51
51
  #
52
+ # @example use a transaction for block initialization
53
+ # l = RDF::List(graph: graph, wrap_transaction: true) do |list|
54
+ # list << RDF::Literal(1)
55
+ # # list.graph.rollback will rollback all list changes within this block.
56
+ # end
57
+ # list.count #=> 1
58
+ #
52
59
  # @param [RDF::Resource] subject (RDF.nil)
53
60
  # Subject should be an {RDF::Node}, not a {RDF::URI}. A list with an IRI head will not validate, but is commonly used to detect if a list is valid.
54
61
  # @param [RDF::Graph] graph (RDF::Graph.new)
55
62
  # @param [Array<RDF::Term>] values
56
63
  # Any values which are not terms are coerced to `RDF::Literal`.
64
+ # @param [Boolean] wrap_transaction (false)
65
+ # Wraps the callback in a transaction, and replaces the graph with that transaction for the duraction of the callback. This has the effect of allowing any list changes to be made atomically, or rolled back.
57
66
  # @yield [list]
58
67
  # @yieldparam [RDF::List] list
59
- def initialize(subject: nil, graph: nil, values: nil, &block)
68
+ def initialize(subject: nil, graph: nil, values: nil, wrap_transaction: false, &block)
60
69
  @subject = subject || RDF.nil
61
70
  @graph = graph || RDF::Graph.new
62
71
  is_empty = @graph.query({subject: subject, predicate: RDF.first}).empty?
@@ -78,9 +87,25 @@ module RDF
78
87
  end
79
88
 
80
89
  if block_given?
81
- case block.arity
82
- when 1 then block.call(self)
83
- else instance_eval(&block)
90
+ if wrap_transaction
91
+ old_graph = @graph
92
+ begin
93
+ Transaction.begin(@graph, graph_name: @graph.graph_name, mutable: @graph.mutable?) do |trans|
94
+ @graph = trans
95
+ case block.arity
96
+ when 1 then block.call(self)
97
+ else instance_eval(&block)
98
+ end
99
+ trans.execute if trans.mutated?
100
+ end
101
+ ensure
102
+ @graph = old_graph
103
+ end
104
+ else
105
+ case block.arity
106
+ when 1 then block.call(self)
107
+ else instance_eval(&block)
108
+ end
84
109
  end
85
110
  end
86
111
  end
@@ -25,7 +25,7 @@ module RDF
25
25
  #
26
26
  # @example Creating a language-tagged literal (1)
27
27
  # value = RDF::Literal.new("Hello!", language: :en)
28
- # value.has_language? #=> true
28
+ # value.language? #=> true
29
29
  # value.language #=> :en
30
30
  #
31
31
  # @example Creating a language-tagged literal (2)
@@ -35,12 +35,12 @@ module RDF
35
35
  #
36
36
  # @example Creating an explicitly datatyped literal
37
37
  # value = RDF::Literal.new("2009-12-31", datatype: RDF::XSD.date)
38
- # value.has_datatype? #=> true
38
+ # value.datatype? #=> true
39
39
  # value.datatype #=> RDF::XSD.date
40
40
  #
41
41
  # @example Creating an implicitly datatyped literal
42
42
  # value = RDF::Literal.new(Date.today)
43
- # value.has_datatype? #=> true
43
+ # value.datatype? #=> true
44
44
  # value.datatype #=> RDF::XSD.date
45
45
  #
46
46
  # @example Creating implicitly datatyped literals
@@ -225,7 +225,7 @@ module RDF
225
225
  # * The arguments are simple literals or literals typed as xsd:string
226
226
  # * The arguments are plain literals with identical language tags
227
227
  # * The first argument is a plain literal with language tag and the second argument is a simple literal or literal typed as xsd:string
228
- has_language? ?
228
+ language? ?
229
229
  (language == other.language || other.datatype == RDF::URI("http://www.w3.org/2001/XMLSchema#string")) :
230
230
  other.datatype == RDF::URI("http://www.w3.org/2001/XMLSchema#string")
231
231
  end
@@ -289,7 +289,7 @@ module RDF
289
289
  case
290
290
  when self.eql?(other)
291
291
  true
292
- when self.has_language? && self.language.to_s == other.language.to_s
292
+ when self.language? && self.language.to_s == other.language.to_s
293
293
  # Literals with languages can compare if languages are identical
294
294
  self.value_hash == other.value_hash && self.value == other.value
295
295
  when self.simple? && other.simple?
@@ -335,10 +335,10 @@ module RDF
335
335
  #
336
336
  # @return [Boolean] `true` or `false`
337
337
  # @see http://www.w3.org/TR/rdf-concepts/#dfn-plain-literal
338
- def has_language?
338
+ def language?
339
339
  datatype == RDF.langString
340
340
  end
341
- alias_method :language?, :has_language?
341
+ alias_method :has_language?, :language?
342
342
 
343
343
  ##
344
344
  # Returns `true` if this is a datatyped literal.
@@ -347,12 +347,12 @@ module RDF
347
347
  #
348
348
  # @return [Boolean] `true` or `false`
349
349
  # @see http://www.w3.org/TR/rdf-concepts/#dfn-typed-literal
350
- def has_datatype?
350
+ def datatype?
351
351
  !plain? && !language?
352
352
  end
353
- alias_method :datatype?, :has_datatype?
354
- alias_method :typed?, :has_datatype?
355
- alias_method :datatyped?, :has_datatype?
353
+ alias_method :has_datatype?, :datatype?
354
+ alias_method :typed?, :datatype?
355
+ alias_method :datatyped?, :datatype?
356
356
 
357
357
  ##
358
358
  # Returns `true` if the value adheres to the defined grammar of the
@@ -386,16 +386,16 @@ module RDF
386
386
  # This behavior is intuited from SPARQL data-r2/expr-equal/eq-2-2
387
387
  # @return [Boolean]
388
388
  def comperable_datatype?(other)
389
- return false unless self.plain? || self.has_language?
389
+ return false unless self.plain? || self.language?
390
390
 
391
391
  case other
392
392
  when RDF::Literal::Numeric, RDF::Literal::Boolean,
393
393
  RDF::Literal::Date, RDF::Literal::Time, RDF::Literal::DateTime
394
394
  # Invald types can be compared without raising a TypeError if literal has a language (open-eq-08)
395
- !other.valid? && self.has_language?
395
+ !other.valid? && self.language?
396
396
  else
397
397
  # An unknown datatype may not be used for comparison, unless it has a language? (open-eq-8)
398
- self.has_language?
398
+ self.language?
399
399
  end
400
400
  end
401
401
 
@@ -51,11 +51,13 @@ module RDF; class Literal
51
51
  #
52
52
  # @return [Boolean]
53
53
  # @since 1.1.6
54
- def has_timezone?
54
+ def timezone?
55
55
  md = self.to_s.match(GRAMMAR)
56
56
  md && !!md[2]
57
57
  end
58
- alias_method :has_tz?, :has_timezone?
58
+ alias_method :tz?, :timezone?
59
+ alias_method :has_tz?, :timezone?
60
+ alias_method :has_timezone?, :timezone?
59
61
 
60
62
  ##
61
63
  # Returns the value as a string.
@@ -72,7 +74,7 @@ module RDF; class Literal
72
74
  # @since 1.1.6
73
75
  def humanize(lang = :en)
74
76
  d = object.strftime("%A, %d %B %Y")
75
- if has_timezone?
77
+ if timezone?
76
78
  d += if self.tz == 'Z'
77
79
  " UTC"
78
80
  else
@@ -30,7 +30,7 @@ module RDF; class Literal
30
30
  # @see http://www.w3.org/TR/xmlschema11-2/#dateTime
31
31
  def canonicalize!
32
32
  if self.valid?
33
- @string = if has_timezone?
33
+ @string = if timezone?
34
34
  @object.new_offset.new_offset.strftime(FORMAT[0..-4] + 'Z').sub('.000', '')
35
35
  else
36
36
  @object.strftime(FORMAT[0..-4]).sub('.000', '')
@@ -45,7 +45,7 @@ module RDF; class Literal
45
45
  # @return [RDF::Literal]
46
46
  # @see http://www.w3.org/TR/sparql11-query/#func-tz
47
47
  def tz
48
- zone = has_timezone? ? object.zone : ""
48
+ zone = timezone? ? object.zone : ""
49
49
  zone = "Z" if zone == "+00:00"
50
50
  RDF::Literal(zone)
51
51
  end
@@ -85,21 +85,25 @@ module RDF; class Literal
85
85
  #
86
86
  # @return [Boolean]
87
87
  # @since 1.1.6
88
- def has_milliseconds?
88
+ def milliseconds?
89
89
  self.format("%L").to_i > 0
90
90
  end
91
- alias_method :has_ms?, :has_milliseconds?
91
+ alias_method :has_milliseconds?, :milliseconds?
92
+ alias_method :has_ms?, :milliseconds?
93
+ alias_method :ms?, :milliseconds?
92
94
 
93
95
  ##
94
96
  # Does the literal representation include a timezone? Note that this is only possible if initialized using a string, or `:lexical` option.
95
97
  #
96
98
  # @return [Boolean]
97
99
  # @since 1.1.6
98
- def has_timezone?
100
+ def timezone?
99
101
  md = self.to_s.match(GRAMMAR)
100
102
  md && !!md[2]
101
103
  end
102
- alias_method :has_tz?, :has_timezone?
104
+ alias_method :tz?, :timezone?
105
+ alias_method :has_tz?, :timezone?
106
+ alias_method :has_timezone?, :timezone?
103
107
 
104
108
  ##
105
109
  # Returns the `timezone` of the literal. If the
@@ -118,7 +122,7 @@ module RDF; class Literal
118
122
  # @since 1.1.6
119
123
  def humanize(lang = :en)
120
124
  d = object.strftime("%r on %A, %d %B %Y")
121
- if has_timezone?
125
+ if timezone?
122
126
  zone = if self.tz == 'Z'
123
127
  "UTC"
124
128
  else
@@ -42,7 +42,7 @@ module RDF; class Literal
42
42
  # @see http://www.w3.org/TR/xmlschema11-2/#time
43
43
  def canonicalize!
44
44
  if self.valid?
45
- @string = if has_timezone?
45
+ @string = if timezone?
46
46
  @object.new_offset.new_offset.strftime(FORMAT[0..-4] + 'Z').sub('.000', '')
47
47
  else
48
48
  @object.strftime(FORMAT[0..-4]).sub('.000', '')
@@ -57,7 +57,7 @@ module RDF; class Literal
57
57
  # @return [RDF::Literal]
58
58
  # @see http://www.w3.org/TR/sparql11-query/#func-tz
59
59
  def tz
60
- zone = has_timezone? ? object.zone : ""
60
+ zone = timezone? ? object.zone : ""
61
61
  zone = "Z" if zone == "+00:00"
62
62
  RDF::Literal(zone)
63
63
  end
@@ -79,11 +79,13 @@ module RDF; class Literal
79
79
  #
80
80
  # @return [Boolean]
81
81
  # @since 1.1.6
82
- def has_timezone?
82
+ def timezone?
83
83
  md = self.to_s.match(GRAMMAR)
84
84
  md && !!md[2]
85
85
  end
86
- alias_method :has_tz?, :has_timezone?
86
+ alias_method :tz?, :timezone?
87
+ alias_method :has_tz?, :timezone?
88
+ alias_method :has_timezone?, :timezone?
87
89
 
88
90
  ##
89
91
  # Returns the value as a string.
@@ -101,7 +103,7 @@ module RDF; class Literal
101
103
  # @since 1.1.6
102
104
  def humanize(lang = :en)
103
105
  t = object.strftime("%r")
104
- if has_timezone?
106
+ if timezone?
105
107
  t += if self.tz == 'Z'
106
108
  " UTC"
107
109
  else
@@ -13,18 +13,14 @@ module RDF
13
13
  include RDF::Resource
14
14
 
15
15
  ##
16
- # Defines the maximum number of interned Node references that can be held
17
- # cached in memory at any one time.
16
+ # Cache size may be set through {RDF.config} using `node_cache_size`.
18
17
  #
19
18
  # @note caching interned nodes means that two different invocations using the same symbol will result in the same node, which may not be appropriate depending on the graph from which it is used. RDF requires that bnodes with the same label are, in fact, different bnodes, unless they are used within the same document.
20
- CACHE_SIZE = -1 # unlimited by default
21
-
22
- ##
23
19
  # @return [RDF::Util::Cache]
24
20
  # @private
25
21
  def self.cache
26
22
  require 'rdf/util/cache' unless defined?(::RDF::Util::Cache)
27
- @cache ||= RDF::Util::Cache.new(CACHE_SIZE)
23
+ @cache ||= RDF::Util::Cache.new(RDF.config.node_cache_size)
28
24
  end
29
25
 
30
26
  ##
@@ -96,7 +96,7 @@ module RDF
96
96
  @predicate = predicate
97
97
  @object = object
98
98
  end
99
- @id = @options.delete(:id) if @options.has_key?(:id)
99
+ @id = @options.delete(:id) if @options.key?(:id)
100
100
  @graph_name = @options.delete(:graph_name)
101
101
  initialize!
102
102
  end
@@ -136,23 +136,45 @@ module RDF
136
136
  end
137
137
 
138
138
  ##
139
- # Returns `true` to indicate that this value is a statement.
139
+ # @overload statement?
140
+ # Returns `true` if `self` is a {RDF::Statement}.
140
141
  #
141
- # @return [Boolean]
142
- def statement?
143
- true
142
+ # @return [Boolean]
143
+ # @overload statement?(statement)
144
+ # Returns `true` if `self` contains the given {RDF::Statement}.
145
+ #
146
+ # @param [RDF::Statement] statement
147
+ # @return [Boolean]
148
+ def statement?(*args)
149
+ case args.length
150
+ when 0 then true
151
+ when 1 then self == args.first || subject.statement?(*args) || object.statement?(*args)
152
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
153
+ end
144
154
  end
145
155
 
146
156
  ##
147
- # Returns `true` if any element of the statement is not a
157
+ # @overload variable?
158
+ # Returns `true` if any element of the statement is not a
148
159
  # URI, Node or Literal.
149
160
  #
150
- # @return [Boolean]
151
- def variable?
152
- !(has_subject? && subject.constant? &&
153
- has_predicate? && predicate.constant? &&
154
- has_object? && object.constant? &&
155
- (has_graph? ? graph_name.constant? : true))
161
+ # @return [Boolean]
162
+ # @overload variable?(variables)
163
+ # Returns `true` if this statement contains any of the variables.
164
+ #
165
+ # @param [Array<Symbol, #to_sym>] variables
166
+ # @return [Boolean]
167
+ def variable?(*args)
168
+ case args.length
169
+ when 0
170
+ !(subject? && subject.constant? &&
171
+ predicate? && predicate.constant? &&
172
+ object? && object.constant? &&
173
+ (graph? ? graph_name.constant? : true))
174
+ when 1
175
+ to_quad.any? {|t| t.respond_to?(:variable?) && t.variable?(*args)}
176
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
177
+ end
156
178
  end
157
179
 
158
180
  ##
@@ -172,10 +194,10 @@ module RDF
172
194
  ##
173
195
  # @return [Boolean]
174
196
  def valid?
175
- has_subject? && subject.resource? && subject.valid? &&
176
- has_predicate? && predicate.uri? && predicate.valid? &&
177
- has_object? && object.term? && object.valid? &&
178
- (has_graph? ? (graph_name.resource? && graph_name.valid?) : true)
197
+ subject? && subject.resource? && subject.valid? &&
198
+ predicate? && predicate.uri? && predicate.valid? &&
199
+ object? && object.term? && object.valid? &&
200
+ (graph? ? (graph_name.resource? && graph_name.valid?) : true)
179
201
  end
180
202
 
181
203
  ##
@@ -215,32 +237,51 @@ module RDF
215
237
  end
216
238
 
217
239
  ##
218
- # @return [Boolean]
219
- def has_graph?
220
- !!graph_name
240
+ # @overload graph?
241
+ # Returns `true` if the statement has a graph name.
242
+ #
243
+ # @return [Boolean]
244
+ # @overload graph?(name)
245
+ # Returns `true` if `self` contains the given RDF graph_name.
246
+ #
247
+ # @param [RDF::Resource, false] graph_name
248
+ # Use value `false` to query for the default graph_name
249
+ # @return [Boolean]
250
+ def graph?(*args)
251
+ case args.length
252
+ when 0 then !!graph_name
253
+ when 1 then graph_name == args.first
254
+ else raise ArgumentError("wrong number of arguments (given #{args.length}, expected 0 or 1)")
255
+ end
221
256
  end
222
- alias_method :has_name?, :has_graph?
257
+ alias_method :name?, :graph?
258
+ alias_method :has_graph?, :graph?
259
+ alias_method :has_name?, :graph?
223
260
 
224
261
  ##
225
262
  # @return [Boolean]
226
- def has_subject?
263
+ def subject?
227
264
  !!subject
228
265
  end
266
+ alias_method :has_subject?, :subject?
229
267
 
230
268
  ##
231
269
  # @return [Boolean]
232
- def has_predicate?
270
+ def predicate?
233
271
  !!predicate
234
272
  end
273
+ alias_method :has_predicate?, :predicate?
235
274
 
236
275
  ##
237
276
  # @return [Boolean]
238
- def has_object?
277
+ def object?
239
278
  !!object
240
279
  end
280
+ alias_method :has_object?, :object?
241
281
 
242
282
  ##
243
- # Returns `true` if any resource of this statement is a blank node.
283
+ # Returns `true` if any resource of this statement is a blank node
284
+ # or has an embedded statement including a blank node.
244
285
  #
245
286
  # @return [Boolean]
246
287
  # @since 2.0
@@ -312,10 +353,10 @@ module RDF
312
353
  # @see RDF::Literal#eql?
313
354
  # @see RDF::Query::Variable#eql?
314
355
  def ===(other)
315
- return false if has_object? && !object.eql?(other.object)
316
- return false if has_predicate? && !predicate.eql?(other.predicate)
317
- return false if has_subject? && !subject.eql?(other.subject)
318
- return false if has_graph? && !graph_name.eql?(other.graph_name)
356
+ return false if object? && !object.eql?(other.object)
357
+ return false if predicate? && !predicate.eql?(other.predicate)
358
+ return false if subject? && !subject.eql?(other.subject)
359
+ return false if graph? && !graph_name.eql?(other.graph_name)
319
360
  return true
320
361
  end
321
362
 
@@ -359,6 +400,13 @@ module RDF
359
400
  end
360
401
  alias_method :to_a, :to_triple
361
402
 
403
+ ##
404
+ # Returns an array of all the non-nil non-statement terms.
405
+ # @return [Array(RDF::Term)]
406
+ def terms
407
+ to_quad.map {|t| t.respond_to?(:terms) ? t.terms : t}.flatten.compact
408
+ end
409
+
362
410
  ##
363
411
  # Canonicalizes each unfrozen term in the statement
364
412
  #
@@ -366,10 +414,10 @@ module RDF
366
414
  # @since 1.0.8
367
415
  # @raise [ArgumentError] if any element cannot be canonicalized.
368
416
  def canonicalize!
369
- self.subject.canonicalize! if has_subject? && !self.subject.frozen?
370
- self.predicate.canonicalize! if has_predicate? && !self.predicate.frozen?
371
- self.object.canonicalize! if has_object? && !self.object.frozen?
372
- self.graph_name.canonicalize! if has_graph? && !self.graph_name.frozen?
417
+ self.subject.canonicalize! if subject? && !self.subject.frozen?
418
+ self.predicate.canonicalize! if predicate? && !self.predicate.frozen?
419
+ self.object.canonicalize! if object? && !self.object.frozen?
420
+ self.graph_name.canonicalize! if graph? && !self.graph_name.frozen?
373
421
  self.validate!
374
422
  @hash = nil
375
423
  self