rdf 3.1.15 → 3.2.4

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.
@@ -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