rdf 3.1.12 → 3.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ff64fa365f10553262446da5494bf2bb592dffe9c409cda37239e0726a5e1f4d
4
- data.tar.gz: 6915405e0bc437cf0be2a88697145757131ea1d054040b9e7823c26c998a8568
3
+ metadata.gz: 2224a9a63fc05ccc786d780252f85ae706edd75f44ee7b459fedc824e53a9098
4
+ data.tar.gz: 7768cfaff9ccfc49f4f96fcf896b084250a8d973277d113c87b8e90a5d7c818d
5
5
  SHA512:
6
- metadata.gz: 0b73a1e41bdb9c53d7dcff97c2b14f785b1f02be8233dcf8ffdd36f9fbc426dcdff5e0af4cb0a31e11fd5edcc76442a2fe6f9d0c1483855a91e340b407ee4753
7
- data.tar.gz: d93d42dcd04f9ff35676a43d1a71b3e84c5fe1a94118a3b0dd7e94aa708e23e5bb0310fb136fa98956b192f7098eb48fe25a91d22c0287e66041a7f73a704b15
6
+ metadata.gz: bb59046c5aaa422b005d58b1f25eb8d9e2acd967116c55d2e657abb269256c1dc1c2706ebf555a82ddc3f1e3bddba23ce3d0f0f6581a5180ae7d9989764aee5b
7
+ data.tar.gz: 13592fb59a53b641a970abc239e3c561e4c2ba1f2c85a1a7fe2003a897dd8305f3127fba4106a330a0fadff0083d66bc0d1d8572c30504eba369902d7fefec42
data/README.md CHANGED
@@ -398,16 +398,16 @@ from BNode identity (i.e., they each entail the other)
398
398
 
399
399
  ## Dependencies
400
400
 
401
- * [Ruby](https://ruby-lang.org/) (>= 2.2)
401
+ * [Ruby](https://ruby-lang.org/) (>= 2.6)
402
402
  * [LinkHeader][] (>= 0.0.8)
403
- * Soft dependency on [RestClient][] (>= 1.7)
403
+ * Soft dependency on [RestClient][] (>= 2.1)
404
404
 
405
405
  ## Installation
406
406
 
407
407
  The recommended installation method is via [RubyGems](https://rubygems.org/).
408
408
  To install the latest official release of RDF.rb, do:
409
409
 
410
- % [sudo] gem install rdf # Ruby 2+
410
+ % [sudo] gem install rdf # Ruby 2.6+
411
411
 
412
412
  ## Download
413
413
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 3.1.12
1
+ 3.2.2
data/lib/rdf/cli.rb CHANGED
@@ -256,8 +256,7 @@ module RDF
256
256
  lambda: ->(argv, opts) do
257
257
  writer_class = RDF::Writer.for(opts[:output_format]) || RDF::NTriples::Writer
258
258
  out = opts[:output]
259
- opts = opts.merge(prefixes: {})
260
- writer_opts = opts.merge(standard_prefixes: true)
259
+ writer_opts = {prefixes: {}, standard_prefixes: true}.merge(opts)
261
260
  writer_class.new(out, **writer_opts) do |writer|
262
261
  writer << repository
263
262
  end
@@ -536,6 +535,8 @@ module RDF
536
535
  count = 0
537
536
  self.parse(args, **options) do |reader|
538
537
  reader.each_statement {|st| @repository << st}
538
+ # Remember prefixes from reading
539
+ options[:prefixes] ||= reader.prefixes
539
540
  end
540
541
  secs = Time.new - start
541
542
  options[:logger].info "Parsed #{repository.count} statements with #{@readers.join(', ')} in #{secs} seconds @ #{count/secs} statements/second."
@@ -43,6 +43,7 @@ module RDF; class Literal
43
43
  # Can't use simple %f transformation due to special requirements from
44
44
  # N3 tests in representation
45
45
  @string = case
46
+ when @object.nil? then 'NaN'
46
47
  when @object.nan? then 'NaN'
47
48
  when @object.infinite? then @object.to_s[0...-'inity'.length].upcase
48
49
  when @object.zero? then '0.0E0'
@@ -11,6 +11,9 @@ module RDF; class Literal
11
11
  # @return [Integer] `-1`, `0`, or `1`
12
12
  # @since 0.3.0
13
13
  def <=>(other)
14
+ # If lexically invalid, use regular literal testing
15
+ return super unless self.valid? && (!other.respond_to?(:valid?) || other.valid?)
16
+
14
17
  case other
15
18
  when ::Numeric
16
19
  to_d <=> other
@@ -30,11 +33,10 @@ module RDF; class Literal
30
33
  # @since 0.3.0
31
34
  def ==(other)
32
35
  # If lexically invalid, use regular literal testing
33
- return super unless self.valid?
36
+ return super unless self.valid? && (!other.respond_to?(:valid?) || other.valid?)
34
37
 
35
38
  case other
36
39
  when Literal::Numeric
37
- return super unless other.valid?
38
40
  (cmp = (self <=> other)) ? cmp.zero? : false
39
41
  when RDF::URI, RDF::Node
40
42
  # Interpreting SPARQL data-r2/expr-equal/eq-2-2, numeric can't be compared with other types
@@ -166,12 +166,12 @@ module RDF
166
166
  @object = value.freeze
167
167
  @string = lexical if lexical
168
168
  @string = value if !defined?(@string) && value.is_a?(String)
169
- @string = @string.encode(Encoding::UTF_8).freeze if @string
170
- @object = @string if @string && @object.is_a?(String)
169
+ @string = @string.encode(Encoding::UTF_8).freeze if instance_variable_defined?(:@string)
170
+ @object = @string if instance_variable_defined?(:@string) && @object.is_a?(String)
171
171
  @language = language.to_s.downcase.to_sym if language
172
172
  @datatype = RDF::URI(datatype).freeze if datatype
173
173
  @datatype ||= self.class.const_get(:DATATYPE) if self.class.const_defined?(:DATATYPE)
174
- @datatype ||= @language ? RDF.langString : RDF::URI("http://www.w3.org/2001/XMLSchema#string")
174
+ @datatype ||= instance_variable_defined?(:@language) && @language ? RDF.langString : RDF::URI("http://www.w3.org/2001/XMLSchema#string")
175
175
  end
176
176
 
177
177
  ##
@@ -179,7 +179,7 @@ module RDF
179
179
  #
180
180
  # @return [String]
181
181
  def value
182
- @string || to_s
182
+ instance_variable_defined?(:@string) && @string || to_s
183
183
  end
184
184
 
185
185
  ##
@@ -308,6 +308,37 @@ module RDF
308
308
  end
309
309
  alias_method :===, :==
310
310
 
311
+ ##
312
+ # Compares `self` to `other` for sorting purposes (with type check).
313
+ #
314
+ # @param [Object] other
315
+ # @return [Integer] `-1`, `0`, or `1`
316
+ def <=>(other)
317
+ case other
318
+ when Literal
319
+ case
320
+ when self.eql?(other)
321
+ 0
322
+ when self.language? && other.language?
323
+ # Literals with languages can compare if languages are identical
324
+ self.to_s <=> other.to_s
325
+ when self.simple? && other.simple?
326
+ self.to_s <=> other.to_s
327
+ when !self.valid?
328
+ type_error("#{self.inspect} is invalid") || 0
329
+ when !other.valid?
330
+ type_error("#{other.inspect} is invalid") || 0
331
+ when self.comperable_datatype2?(other)
332
+ self.object <=> other.object
333
+ else
334
+ type_error("#{self.inspect} and #{other.inspect} are not comperable") || 0
335
+ end
336
+ when String
337
+ self.simple? && self.value <=> other
338
+ else 1
339
+ end
340
+ end
341
+
311
342
  ##
312
343
  # Returns `true` if this is a plain literal. A plain literal
313
344
  # may have a language, but may not have a datatype. For
@@ -399,6 +430,26 @@ module RDF
399
430
  end
400
431
  end
401
432
 
433
+ ##
434
+ # Returns `true` if the literals are comperable.
435
+ #
436
+ # Used for <=> operator.
437
+ #
438
+ # @return [Boolean]
439
+ def comperable_datatype2?(other)
440
+ case self
441
+ when RDF::Literal::Numeric, RDF::Literal::Boolean
442
+ case other
443
+ when RDF::Literal::Numeric, RDF::Literal::Boolean
444
+ true
445
+ else
446
+ false
447
+ end
448
+ else
449
+ self.datatype == other.datatype
450
+ end
451
+ end
452
+
402
453
  ##
403
454
  # Converts this literal into its canonical lexical representation.
404
455
  #
@@ -301,7 +301,7 @@ module RDF
301
301
  # @see RDF::Literal#==
302
302
  # @see RDF::Query::Variable#==
303
303
  def eql?(other)
304
- other.is_a?(Statement) && self == other && (self.graph_name || false) == (other.graph_name || false)
304
+ other.is_a?(Statement) && self.to_a.eql?(other.to_a) && (self.graph_name || false) == (other.graph_name || false)
305
305
  end
306
306
 
307
307
  ##
data/lib/rdf/model/uri.rb CHANGED
@@ -621,16 +621,22 @@ module RDF
621
621
  end
622
622
 
623
623
  ##
624
- # Returns a qualified name (QName) for this URI based on available vocabularies, if possible.
624
+ # Returns a qualified name (QName) as a tuple of `[prefix, suffix]` for this URI based on available vocabularies, if possible.
625
625
  #
626
626
  # @example
627
627
  # RDF::URI('http://www.w3.org/2000/01/rdf-schema#').qname #=> [:rdfs, nil]
628
628
  # RDF::URI('http://www.w3.org/2000/01/rdf-schema#label').qname #=> [:rdfs, :label]
629
629
  # RDF::RDFS.label.qname #=> [:rdfs, :label]
630
630
  #
631
+ # @param [Hash{Symbol => String}] prefixes
632
+ # Explicit set of prefixes to look for matches, defaults to loaded vocabularies.
631
633
  # @return [Array(Symbol, Symbol)] or `nil` if no QName found
632
- def qname
633
- if self.to_s =~ %r([:/#]([^:/#]*)$)
634
+ def qname(prefixes: nil)
635
+ if prefixes
636
+ prefixes.each do |prefix, uri|
637
+ return [prefix, self.to_s[uri.length..-1].to_sym] if self.start_with?(uri)
638
+ end
639
+ elsif self.to_s =~ %r([:/#]([^:/#]*)$)
634
640
  local_name = $1
635
641
  vocab_uri = local_name.empty? ? self.to_s : self.to_s[0...-(local_name.length)]
636
642
  Vocabulary.each do |vocab|
@@ -655,9 +661,11 @@ module RDF
655
661
  ##
656
662
  # Returns a string version of the QName or the full IRI
657
663
  #
664
+ # @param [Hash{Symbol => String}] prefixes
665
+ # Explicit set of prefixes to look for matches, defaults to loaded vocabularies.
658
666
  # @return [String] or `nil`
659
- def pname
660
- (q = self.qname) ? q.join(":") : to_s
667
+ def pname(prefixes: nil)
668
+ (q = self.qname(prefixes: prefixes)) ? q.join(":") : to_s
661
669
  end
662
670
 
663
671
  ##
data/lib/rdf/nquads.rb CHANGED
@@ -69,9 +69,9 @@ module RDF
69
69
 
70
70
  begin
71
71
  unless blank? || read_comment
72
- subject = read_uriref || read_node || read_embTriple || fail_subject
72
+ subject = read_uriref || read_node || read_quotedTriple || fail_subject
73
73
  predicate = read_uriref(intern: true) || fail_predicate
74
- object = read_uriref || read_node || read_literal || read_embTriple || fail_object
74
+ object = read_uriref || read_node || read_literal || read_quotedTriple || fail_object
75
75
  graph_name = read_uriref || read_node
76
76
  if validate? && !read_eos
77
77
  log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
@@ -213,7 +213,7 @@ module RDF::NTriples
213
213
  begin
214
214
  read_statement
215
215
  rescue RDF::ReaderError
216
- value = read_uriref || read_node || read_literal || read_embTriple
216
+ value = read_uriref || read_node || read_literal || read_quotedTriple
217
217
  log_recover
218
218
  value
219
219
  end
@@ -229,9 +229,9 @@ module RDF::NTriples
229
229
 
230
230
  begin
231
231
  unless blank? || read_comment
232
- subject = read_uriref || read_node || read_embTriple || fail_subject
232
+ subject = read_uriref || read_node || read_quotedTriple || fail_subject
233
233
  predicate = read_uriref(intern: true) || fail_predicate
234
- object = read_uriref || read_node || read_literal || read_embTriple || fail_object
234
+ object = read_uriref || read_node || read_literal || read_quotedTriple || fail_object
235
235
 
236
236
  if validate? && !read_eos
237
237
  log_error("Expected end of statement (found: #{current_line.inspect})", lineno: lineno, exception: RDF::ReaderError)
@@ -247,11 +247,11 @@ module RDF::NTriples
247
247
 
248
248
  ##
249
249
  # @return [RDF::Statement]
250
- def read_embTriple
250
+ def read_quotedTriple
251
251
  if @options[:rdfstar] && match(ST_START)
252
- subject = read_uriref || read_node || read_embTriple || fail_subject
252
+ subject = read_uriref || read_node || read_quotedTriple || fail_subject
253
253
  predicate = read_uriref(intern: true) || fail_predicate
254
- object = read_uriref || read_node || read_literal || read_embTriple || fail_object
254
+ object = read_uriref || read_node || read_literal || read_quotedTriple || fail_object
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
@@ -227,7 +227,7 @@ module RDF::NTriples
227
227
  # @param [RDF::Statement] statement
228
228
  # @param [Hash{Symbol => Object}] options ({})
229
229
  # @return [String]
230
- def format_embTriple(statement, **options)
230
+ def format_quotedTriple(statement, **options)
231
231
  "<<%s %s %s>>" % statement.to_a.map { |value| format_term(value, **options) }
232
232
  end
233
233
  ##
@@ -59,6 +59,12 @@ module RDF; class Query
59
59
  super
60
60
  end
61
61
 
62
+ ##
63
+ # Create a new pattern from the quads, recursivly dupping sub-patterns.
64
+ def dup
65
+ self.class.from(self.to_quad.map {|t| t.is_a?(RDF::Query::Pattern) ? t.dup : t})
66
+ end
67
+
62
68
  ##
63
69
  # Any additional options for this pattern.
64
70
  #
@@ -23,10 +23,13 @@ class RDF::Query
23
23
  class Solution
24
24
  # Undefine all superfluous instance methods:
25
25
  alias_method :__send, :send
26
+
27
+ # Temporarily remember instance method for deprecation message in `method_missing`.
28
+ INSTANCE_METHODS = instance_methods
26
29
  undef_method(*instance_methods.
27
30
  map(&:to_s).
28
31
  select {|m| m.match?(/^\w+$/)}.
29
- reject {|m| %w(object_id dup instance_eval inspect to_s private_methods class should should_not pretty_print).include?(m) || m[0,2] == '__'}.
32
+ reject {|m| %w(object_id dup instance_eval inspect to_s private_methods public_methods class method pretty_print).include?(m) || m[0,2] == '__'}.
30
33
  map(&:to_sym))
31
34
 
32
35
  include Enumerable
@@ -344,6 +347,12 @@ class RDF::Query
344
347
  # @return [RDF::Term]
345
348
  def method_missing(name, *args, &block)
346
349
  if args.empty? && @bindings.key?(name.to_sym)
350
+ if INSTANCE_METHODS.include?(name)
351
+ warn "[DEPRECATION] RDF::Query::Solution##{name} is an overridden instance method.\n" +
352
+ "Its use as a solution accessor is deprecated and will be removed in a future version.\n" +
353
+ "Use #[] for safe access.\n" +
354
+ "Called from #{Gem.location_of_caller.join(':')}"
355
+ end
347
356
  @bindings[name.to_sym]
348
357
  else
349
358
  super # raises NoMethodError
data/lib/rdf/reader.rb CHANGED
@@ -647,7 +647,7 @@ module RDF
647
647
  ##
648
648
  # @return [String]
649
649
  def readline
650
- @line = @line_rest || @input.readline
650
+ @line = instance_variable_defined?(:@line_rest) && @line_rest || @input.readline
651
651
  @line, @line_rest = @line.split("\r", 2)
652
652
  @line = String.new if @line.nil? # not frozen
653
653
  @line.chomp!
@@ -243,17 +243,20 @@ module RDF
243
243
  #
244
244
  # @see RDF::Repository
245
245
  module Implementation
246
- require 'hamster'
247
246
  DEFAULT_GRAPH = false
247
+
248
+ ##
249
+ # @deprecated moved to {RDF::Transaction::SerializedTransaction}
250
+ SerializedTransaction = RDF::Transaction::SerializedTransaction
248
251
 
249
252
  ##
250
253
  # @private
251
254
  def self.extend_object(obj)
252
255
  obj.instance_variable_set(:@data, obj.options.delete(:data) ||
253
- Hamster::Hash.new)
256
+ Hash.new)
254
257
  obj.instance_variable_set(:@tx_class,
255
258
  obj.options.delete(:transaction_class) ||
256
- SerializedTransaction)
259
+ RDF::Transaction::SerializedTransaction)
257
260
  super
258
261
  end
259
262
 
@@ -263,7 +266,6 @@ module RDF
263
266
  def supports?(feature)
264
267
  case feature.to_sym
265
268
  when :graph_name then @options[:with_graph_name]
266
- when :inference then false # forward-chaining inference
267
269
  when :validity then @options.fetch(:with_validity, true)
268
270
  when :literal_equality then true
269
271
  when :atomic_write then true
@@ -381,7 +383,7 @@ module RDF
381
383
  ##
382
384
  # @see RDF::Dataset#isolation_level
383
385
  def isolation_level
384
- :serializable
386
+ :snapshot
385
387
  end
386
388
 
387
389
  ##
@@ -471,7 +473,7 @@ module RDF
471
473
  # @private
472
474
  # @see RDF::Mutable#clear
473
475
  def clear_statements
474
- @data = @data.clear
476
+ @data = @data.class.new
475
477
  end
476
478
 
477
479
  ##
@@ -513,14 +515,11 @@ module RDF
513
515
  unless statement_in?(data, statement)
514
516
  s, p, o, c = statement.to_quad
515
517
  c ||= DEFAULT_GRAPH
516
-
517
- return data.put(c) do |subs|
518
- (subs || Hamster::Hash.new).put(s) do |preds|
519
- (preds || Hamster::Hash.new).put(p) do |objs|
520
- (objs || Hamster::Hash.new).put(o, statement.options)
521
- end
522
- end
523
- end
518
+
519
+ data = data.has_key?(c) ? data.dup : data.merge(c => {})
520
+ data[c] = data[c].has_key?(s) ? data[c].dup : data[c].merge(s => {})
521
+ data[c][s] = data[c][s].has_key?(p) ? data[c][s].dup : data[c][s].merge(p => {})
522
+ data[c][s][p] = data[c][s][p].merge(o => statement.options)
524
523
  end
525
524
  data
526
525
  end
@@ -529,93 +528,18 @@ module RDF
529
528
  # @private
530
529
  # @return [Hamster::Hash] a new, updated hamster hash
531
530
  def delete_from(data, statement)
532
- if statement_in?(data, statement)
531
+ if has_statement_in?(data, statement)
533
532
  s, p, o, g = statement.to_quad
534
533
  g = DEFAULT_GRAPH unless supports?(:graph_name)
535
534
  g ||= DEFAULT_GRAPH
536
535
 
537
- os = data[g][s][p].delete(o)
538
- ps = os.empty? ? data[g][s].delete(p) : data[g][s].put(p, os)
539
- ss = ps.empty? ? data[g].delete(s) : data[g].put(s, ps)
540
- return ss.empty? ? data.delete(g) : data.put(g, ss)
536
+ os = data[g][s][p].dup.delete_if {|k,v| k == o}
537
+ ps = os.empty? ? data[g][s].dup.delete_if {|k,v| k == p} : data[g][s].merge(p => os)
538
+ ss = ps.empty? ? data[g].dup.delete_if {|k,v| k == s} : data[g].merge(s => ps)
539
+ return ss.empty? ? data.dup.delete_if {|k,v| k == g} : data.merge(g => ss)
541
540
  end
542
541
  data
543
542
  end
544
-
545
- ##
546
- # A transaction for the Hamster-based `RDF::Repository::Implementation`
547
- # with full serializability.
548
- #
549
- # @todo refactor me!
550
- # @see RDF::Transaction
551
- class SerializedTransaction < Transaction
552
- ##
553
- # @see Transaction#initialize
554
- def initialize(*args, **options, &block)
555
- super(*args, **options, &block)
556
- @base_snapshot = @snapshot
557
- end
558
-
559
- ##
560
- # Inserts the statement to the transaction's working snapshot.
561
- #
562
- # @see Transaction#insert_statement
563
- def insert_statement(statement)
564
- @snapshot = @snapshot.class
565
- .new(data: @snapshot.send(:insert_to,
566
- @snapshot.send(:data),
567
- process_statement(statement)))
568
- end
569
-
570
- ##
571
- # Deletes the statement from the transaction's working snapshot.
572
- #
573
- # @see Transaction#insert_statement
574
- def delete_statement(statement)
575
- @snapshot = @snapshot.class
576
- .new(data: @snapshot.send(:delete_from,
577
- @snapshot.send(:data),
578
- process_statement(statement)))
579
- end
580
-
581
- ##
582
- # @see RDF::Dataset#isolation_level
583
- def isolation_level
584
- :serializable
585
- end
586
-
587
- ##
588
- # @note this is a simple object equality check.
589
- #
590
- # @see RDF::Transaction#mutated?
591
- def mutated?
592
- !@snapshot.send(:data).equal?(repository.send(:data))
593
- end
594
-
595
- ##
596
- # Replaces repository data with the transaction's snapshot in a safely
597
- # serializable fashion.
598
- #
599
- # @note this transaction uses a pessimistic merge strategy which
600
- # fails the transaction if any data has changed in the repository
601
- # since transaction start time. However, the specific guarantee is
602
- # softer: multiple concurrent conflicting transactions will not
603
- # succeed. We may choose to implement a less pessimistic merge
604
- # strategy as a non-breaking change.
605
- #
606
- # @raise [TransactionError] when the transaction can't be merged.
607
- # @see Transaction#execute
608
- def execute
609
- raise TransactionError, 'Cannot execute a rolled back transaction. ' \
610
- 'Open a new one instead.' if @rolledback
611
-
612
- raise TransactionError, 'Error merging transaction. Repository' \
613
- 'has changed during transaction time.' unless
614
- repository.send(:data).equal? @base_snapshot.send(:data)
615
-
616
- repository.send(:data=, @snapshot.send(:data))
617
- end
618
- end
619
543
  end # Implementation
620
544
  end # Repository
621
545
  end # RDF
@@ -247,7 +247,7 @@ module RDF
247
247
  # @raise [TransactionError] if the transaction can't be applied
248
248
  def execute
249
249
  raise TransactionError, 'Cannot execute a rolled back transaction. ' \
250
- 'Open a new one instead.' if @rolledback
250
+ 'Open a new one instead.' if instance_variable_defined?(:@rolledback) && @rolledback
251
251
  @changes.apply(@repository)
252
252
  end
253
253
 
@@ -322,7 +322,81 @@ module RDF
322
322
  end
323
323
 
324
324
  public
325
-
325
+
326
+ ##
327
+ # A transaction with full serializability.
328
+ #
329
+ # @todo refactor me!
330
+ # @see RDF::Transaction
331
+ class SerializedTransaction < Transaction
332
+ ##
333
+ # @see Transaction#initialize
334
+ def initialize(*args, **options, &block)
335
+ super(*args, **options, &block)
336
+ @base_snapshot = @snapshot
337
+ end
338
+
339
+ ##
340
+ # Inserts the statement to the transaction's working snapshot.
341
+ #
342
+ # @see Transaction#insert_statement
343
+ def insert_statement(statement)
344
+ @snapshot = @snapshot.class
345
+ .new(data: @snapshot.send(:insert_to,
346
+ @snapshot.send(:data),
347
+ process_statement(statement)))
348
+ end
349
+
350
+ ##
351
+ # Deletes the statement from the transaction's working snapshot.
352
+ #
353
+ # @see Transaction#insert_statement
354
+ def delete_statement(statement)
355
+ @snapshot = @snapshot.class
356
+ .new(data: @snapshot.send(:delete_from,
357
+ @snapshot.send(:data),
358
+ process_statement(statement)))
359
+ end
360
+
361
+ ##
362
+ # @see RDF::Dataset#isolation_level
363
+ def isolation_level
364
+ :serializable
365
+ end
366
+
367
+ ##
368
+ # @note this is a simple object equality check.
369
+ #
370
+ # @see RDF::Transaction#mutated?
371
+ def mutated?
372
+ !@snapshot.send(:data).equal?(repository.send(:data))
373
+ end
374
+
375
+ ##
376
+ # Replaces repository data with the transaction's snapshot in a safely
377
+ # serializable fashion.
378
+ #
379
+ # @note this transaction uses a pessimistic merge strategy which
380
+ # fails the transaction if any data has changed in the repository
381
+ # since transaction start time. However, the specific guarantee is
382
+ # softer: multiple concurrent conflicting transactions will not
383
+ # succeed. We may choose to implement a less pessimistic merge
384
+ # strategy as a non-breaking change.
385
+ #
386
+ # @raise [TransactionError] when the transaction can't be merged.
387
+ # @see Transaction#execute
388
+ def execute
389
+ raise TransactionError, 'Cannot execute a rolled back transaction. ' \
390
+ 'Open a new one instead.' if instance_variable_defined?(:@rolledback) && @rolledback
391
+
392
+ raise TransactionError, 'Error merging transaction. Repository' \
393
+ 'has changed during transaction time.' unless
394
+ repository.send(:data).equal? @base_snapshot.send(:data)
395
+
396
+ repository.send(:data=, @snapshot.send(:data))
397
+ end
398
+ end # SerializedTransaction
399
+
326
400
  ##
327
401
  # An error class for transaction failures.
328
402
  #
data/lib/rdf/util/file.rb CHANGED
@@ -98,7 +98,7 @@ module RDF; module Util
98
98
  headers: response.headers
99
99
  }
100
100
 
101
- remote_document = RemoteDocument.new(response.body, document_options)
101
+ RemoteDocument.new(response.body, document_options)
102
102
  when 300..399
103
103
  # Document base is redirected location
104
104
  # Location may be relative
@@ -215,7 +215,7 @@ module RDF; module Util
215
215
  headers: response.headers
216
216
  }
217
217
 
218
- remote_document = RemoteDocument.new(response.body, document_options)
218
+ RemoteDocument.new(response.body, document_options)
219
219
  else
220
220
  raise IOError, "<#{base_uri}>: #{response.status}"
221
221
  end
@@ -17,17 +17,20 @@ module RDF; module Util
17
17
  # @param [Hash{Symbol => Object}] options
18
18
  # @option options [Logger, #<<] :logger
19
19
  # @return [Logger, #write, #<<]
20
- def logger(**options)
21
- logger = options.fetch(:logger, @logger)
22
- logger = @options[:logger] if logger.nil? && @options
20
+ def logger(logger: nil, **options)
21
+ # Guard against undefined instance variables, which may be a warning if used.
22
+ @options = {} unless instance_variable_defined?(:@options) || frozen?
23
+ logger ||= @logger if instance_variable_defined?(:@logger)
24
+ logger = @options[:logger] if logger.nil? && instance_variable_defined?(:@options) && @options
23
25
  if logger.nil?
24
26
  # Unless otherwise specified, use $stderr
25
- logger = (@options || options)[:logger] = IOWrapper.new($stderr)
27
+ logger = IOWrapper.new($stderr)
26
28
 
27
29
  # Reset log_statistics so that it's not inherited across different instances
28
30
  logger.log_statistics.clear if logger.respond_to?(:log_statistics)
29
31
  end
30
- logger = (@options || options)[:logger] = ::Logger.new(::File.open(::File::NULL, "w")) unless logger # Incase false was used, which is frozen
32
+ logger = ::Logger.new(::File.open(::File::NULL, "w")) unless logger # Incase false was used, which is frozen
33
+ @options[:logger] ||= logger if instance_variable_defined?(:@options)
31
34
  logger.extend(LoggerBehavior) unless logger.is_a?(LoggerBehavior)
32
35
  logger
33
36
  end
@@ -70,7 +70,7 @@ module RDF
70
70
  # @return [Enumerator]
71
71
  def each(&block)
72
72
  if self.equal?(Vocabulary)
73
- if @vocabs
73
+ if instance_variable_defined?(:@vocabs) && @vocabs
74
74
  @vocabs.select(&:name).each(&block)
75
75
  else
76
76
  # This is needed since all vocabulary classes are defined using
@@ -356,7 +356,7 @@ module RDF
356
356
  def ontology(*args)
357
357
  case args.length
358
358
  when 0
359
- @ontology
359
+ @ontology if instance_variable_defined?(:@ontology)
360
360
  else
361
361
  uri, options = args
362
362
  URI.cache.delete(uri.to_s.to_sym) # Clear any previous entry
@@ -507,7 +507,7 @@ module RDF
507
507
  end
508
508
 
509
509
  # Also include the ontology, if it's not also a property
510
- @ontology.each_statement(&block) if @ontology && @ontology != self
510
+ @ontology.each_statement(&block) if self.ontology && self.ontology != self
511
511
  end
512
512
 
513
513
  ##
@@ -574,6 +574,7 @@ module RDF
574
574
  term_defs
575
575
  end
576
576
 
577
+ #require 'byebug'; byebug
577
578
  # Pass over embedded_defs with anonymous references, once
578
579
  embedded_defs.each do |term, attributes|
579
580
  attributes.each do |ak, avs|
@@ -1234,16 +1235,16 @@ module RDF
1234
1235
  values = values.map do |value|
1235
1236
  if value.is_a?(Literal) && %w(: comment definition notation note editorialNote).include?(k.to_s)
1236
1237
  "%(#{value.to_s.gsub('(', '\(').gsub(')', '\)')}).freeze"
1237
- # elsif value.is_a?(RDF::Vocabulary::Term)
1238
- # value.to_ruby(indent: indent + " ")
1238
+ elsif value.node? && value.is_a?(RDF::Vocabulary::Term)
1239
+ "#{value.to_ruby(indent: indent + " ")}.freeze"
1239
1240
  elsif value.is_a?(RDF::Term)
1240
1241
  "#{value.to_s.inspect}.freeze"
1241
1242
  elsif value.is_a?(RDF::List)
1242
1243
  list_elements = value.map do |u|
1243
1244
  if u.uri?
1244
1245
  "#{u.to_s.inspect}.freeze"
1245
- # elsif u.respond_to?(:to_ruby)
1246
- # u.to_ruby(indent: indent + " ")
1246
+ elsif u.node? && u.respond_to?(:to_ruby)
1247
+ u.to_ruby(indent: indent + " ")
1247
1248
  else
1248
1249
  "#{u.to_s.inspect}.freeze"
1249
1250
  end
data/lib/rdf/writer.rb CHANGED
@@ -516,7 +516,7 @@ module RDF
516
516
  when RDF::Literal then format_literal(term, **options)
517
517
  when RDF::URI then format_uri(term, **options)
518
518
  when RDF::Node then format_node(term, **options)
519
- when RDF::Statement then format_embTriple(term, **options)
519
+ when RDF::Statement then format_quotedTriple(term, **options)
520
520
  else nil
521
521
  end
522
522
  end
@@ -574,7 +574,7 @@ module RDF
574
574
  # @return [String]
575
575
  # @raise [NotImplementedError] unless implemented in subclass
576
576
  # @abstract
577
- def format_embTriple(value, **options)
577
+ def format_quotedTriple(value, **options)
578
578
  raise NotImplementedError.new("#{self.class}#format_statement") # override in subclasses
579
579
  end
580
580
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rdf
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.12
4
+ version: 3.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Arto Bendiken
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2021-02-16 00:00:00.000000000 Z
13
+ date: 2022-01-03 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: link_header
@@ -32,76 +32,62 @@ dependencies:
32
32
  - - ">="
33
33
  - !ruby/object:Gem::Version
34
34
  version: 0.0.8
35
- - !ruby/object:Gem::Dependency
36
- name: hamster
37
- requirement: !ruby/object:Gem::Requirement
38
- requirements:
39
- - - "~>"
40
- - !ruby/object:Gem::Version
41
- version: '3.0'
42
- type: :runtime
43
- prerelease: false
44
- version_requirements: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - "~>"
47
- - !ruby/object:Gem::Version
48
- version: '3.0'
49
35
  - !ruby/object:Gem::Dependency
50
36
  name: rdf-spec
51
37
  requirement: !ruby/object:Gem::Requirement
52
38
  requirements:
53
39
  - - "~>"
54
40
  - !ruby/object:Gem::Version
55
- version: '3.1'
41
+ version: '3.2'
56
42
  type: :development
57
43
  prerelease: false
58
44
  version_requirements: !ruby/object:Gem::Requirement
59
45
  requirements:
60
46
  - - "~>"
61
47
  - !ruby/object:Gem::Version
62
- version: '3.1'
48
+ version: '3.2'
63
49
  - !ruby/object:Gem::Dependency
64
50
  name: rdf-turtle
65
51
  requirement: !ruby/object:Gem::Requirement
66
52
  requirements:
67
53
  - - "~>"
68
54
  - !ruby/object:Gem::Version
69
- version: '3.1'
55
+ version: '3.2'
70
56
  type: :development
71
57
  prerelease: false
72
58
  version_requirements: !ruby/object:Gem::Requirement
73
59
  requirements:
74
60
  - - "~>"
75
61
  - !ruby/object:Gem::Version
76
- version: '3.1'
62
+ version: '3.2'
77
63
  - !ruby/object:Gem::Dependency
78
64
  name: rdf-vocab
79
65
  requirement: !ruby/object:Gem::Requirement
80
66
  requirements:
81
67
  - - "~>"
82
68
  - !ruby/object:Gem::Version
83
- version: '3.1'
69
+ version: '3.2'
84
70
  type: :development
85
71
  prerelease: false
86
72
  version_requirements: !ruby/object:Gem::Requirement
87
73
  requirements:
88
74
  - - "~>"
89
75
  - !ruby/object:Gem::Version
90
- version: '3.1'
76
+ version: '3.2'
91
77
  - !ruby/object:Gem::Dependency
92
78
  name: rdf-xsd
93
79
  requirement: !ruby/object:Gem::Requirement
94
80
  requirements:
95
81
  - - "~>"
96
82
  - !ruby/object:Gem::Version
97
- version: '3.1'
83
+ version: '3.2'
98
84
  type: :development
99
85
  prerelease: false
100
86
  version_requirements: !ruby/object:Gem::Requirement
101
87
  requirements:
102
88
  - - "~>"
103
89
  - !ruby/object:Gem::Version
104
- version: '3.1'
90
+ version: '3.2'
105
91
  - !ruby/object:Gem::Dependency
106
92
  name: rest-client
107
93
  requirement: !ruby/object:Gem::Requirement
@@ -122,14 +108,14 @@ dependencies:
122
108
  requirements:
123
109
  - - "~>"
124
110
  - !ruby/object:Gem::Version
125
- version: '3.9'
111
+ version: '3.10'
126
112
  type: :development
127
113
  prerelease: false
128
114
  version_requirements: !ruby/object:Gem::Requirement
129
115
  requirements:
130
116
  - - "~>"
131
117
  - !ruby/object:Gem::Version
132
- version: '3.9'
118
+ version: '3.10'
133
119
  - !ruby/object:Gem::Dependency
134
120
  name: rspec-its
135
121
  requirement: !ruby/object:Gem::Requirement
@@ -150,14 +136,14 @@ dependencies:
150
136
  requirements:
151
137
  - - "~>"
152
138
  - !ruby/object:Gem::Version
153
- version: '3.7'
139
+ version: '3.14'
154
140
  type: :development
155
141
  prerelease: false
156
142
  version_requirements: !ruby/object:Gem::Requirement
157
143
  requirements:
158
144
  - - "~>"
159
145
  - !ruby/object:Gem::Version
160
- version: '3.7'
146
+ version: '3.14'
161
147
  - !ruby/object:Gem::Dependency
162
148
  name: yard
163
149
  requirement: !ruby/object:Gem::Requirement
@@ -178,28 +164,28 @@ dependencies:
178
164
  requirements:
179
165
  - - "~>"
180
166
  - !ruby/object:Gem::Version
181
- version: '1.2'
167
+ version: '1.8'
182
168
  type: :development
183
169
  prerelease: false
184
170
  version_requirements: !ruby/object:Gem::Requirement
185
171
  requirements:
186
172
  - - "~>"
187
173
  - !ruby/object:Gem::Version
188
- version: '1.2'
174
+ version: '1.8'
189
175
  - !ruby/object:Gem::Dependency
190
176
  name: faraday_middleware
191
177
  requirement: !ruby/object:Gem::Requirement
192
178
  requirements:
193
179
  - - "~>"
194
180
  - !ruby/object:Gem::Version
195
- version: '1.0'
181
+ version: '1.2'
196
182
  type: :development
197
183
  prerelease: false
198
184
  version_requirements: !ruby/object:Gem::Requirement
199
185
  requirements:
200
186
  - - "~>"
201
187
  - !ruby/object:Gem::Version
202
- version: '1.0'
188
+ version: '1.2'
203
189
  description: RDF.rb is a pure-Ruby library for working with Resource Description Framework
204
190
  (RDF) data.
205
191
  email: public-rdf-ruby@w3.org
@@ -296,14 +282,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
296
282
  requirements:
297
283
  - - ">="
298
284
  - !ruby/object:Gem::Version
299
- version: '2.4'
285
+ version: '2.6'
300
286
  required_rubygems_version: !ruby/object:Gem::Requirement
301
287
  requirements:
302
288
  - - ">="
303
289
  - !ruby/object:Gem::Version
304
290
  version: '0'
305
291
  requirements: []
306
- rubygems_version: 3.2.3
292
+ rubygems_version: 3.3.3
307
293
  signing_key:
308
294
  specification_version: 4
309
295
  summary: A Ruby library for working with Resource Description Framework (RDF) data.