rdf 3.1.15 → 3.2.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -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