module RDF::Repository::Implementation
A default Repository implementation supporting atomic writes and serializable transactions.
@see RDF::Repository
Constants
- DEFAULT_GRAPH
Public Class Methods
@private
# File lib/rdf/repository.rb, line 248 def self.extend_object(obj) obj.instance_variable_set(:@data, obj.options.delete(:data) || Hamster::Hash.new) obj.instance_variable_set(:@tx_class, obj.options.delete(:transaction_class) || SerializedTransaction) super end
Public Instance Methods
@see RDF::Mutable#apply_changeset
# File lib/rdf/repository.rb, line 345 def apply_changeset(changeset) data = @data changeset.deletes.each { |del| data = delete_from(data, del) } changeset.inserts.each { |ins| data = insert_to(data, ins) } @data = data end
@private @see RDF::Countable#count
# File lib/rdf/repository.rb, line 274 def count count = 0 @data.each do |_, ss| ss.each do |_, ps| ps.each { |_, os| count += os.size } end end count end
@private @see RDF::Durable#durable?
# File lib/rdf/repository.rb, line 287 def durable? false end
@private @see RDF::Enumerable#each_graph
# File lib/rdf/repository.rb, line 308 def each_graph(&block) if block_given? @data.each_key do |gn| yield RDF::Graph.new(graph_name: (gn == DEFAULT_GRAPH ? nil : gn), data: self) end end enum_graph end
@private @see RDF::Enumerable#each_statement
# File lib/rdf/repository.rb, line 327 def each_statement(&block) if block_given? @data.each do |g, ss| ss.each do |s, ps| ps.each do |p, os| os.each do |o| yield RDF::Statement.new(s, p, o, graph_name: g.equal?(DEFAULT_GRAPH) ? nil : g) end end end end end enum_statement end
@private @see RDF::Enumerable#each_graph
# File lib/rdf/repository.rb, line 301 def graph_names(options = nil, &block) @data.keys.reject { |g| g == DEFAULT_GRAPH }.to_a end
@private @see RDF::Enumerable#has_graph?
# File lib/rdf/repository.rb, line 294 def has_graph?(graph) @data.has_key?(graph) end
@private @see RDF::Enumerable#has_statement?
# File lib/rdf/repository.rb, line 320 def has_statement?(statement) has_statement_in?(@data, statement) end
@see RDF::Dataset#isolation_level
# File lib/rdf/repository.rb, line 354 def isolation_level :serializable end
A readable & queryable snapshot of the repository for isolated reads.
@return [Dataset] an immutable Dataset containing a current snapshot of
the Repository contents.
# File lib/rdf/repository.rb, line 365 def snapshot self.class.new(data: @data).freeze end
@private @see RDF::Enumerable#supports?
# File lib/rdf/repository.rb, line 260 def supports?(feature) case feature.to_sym when :graph_name then @options[:with_graph_name] when :inference then false # forward-chaining inference when :validity then @options.fetch(:with_validity, true) when :atomic_write then true when :snapshots then true else false end end
Protected Instance Methods
@private @see RDF::Mutable#clear
# File lib/rdf/repository.rb, line 439 def clear_statements @data = @data.clear end
@private @return [Hamster::Hash]
# File lib/rdf/repository.rb, line 446 def data @data end
@private @return [Hamster::Hash]
# File lib/rdf/repository.rb, line 453 def data=(hash) @data = hash end
@private @see RDF::Mutable#delete
# File lib/rdf/repository.rb, line 432 def delete_statement(statement) @data = delete_from(@data, statement) end
@private @see RDF::Mutable#insert
# File lib/rdf/repository.rb, line 425 def insert_statement(statement) @data = insert_to(@data, statement) end
Match elements with `eql?`, not `==`
`graph_name` of `false` matches default graph. Unbound variable matches non-false graph name
@private @see RDF::Queryable#query_pattern
# File lib/rdf/repository.rb, line 379 def query_pattern(pattern, options = {}, &block) snapshot = @data if block_given? graph_name = pattern.graph_name subject = pattern.subject predicate = pattern.predicate object = pattern.object cs = snapshot.has_key?(graph_name) ? { graph_name => snapshot[graph_name] } : snapshot cs.each do |c, ss| next unless graph_name.nil? || graph_name == false && !c || graph_name.eql?(c) ss = if subject.nil? || subject.is_a?(RDF::Query::Variable) ss elsif ss.has_key?(subject) { subject => ss[subject] } else [] end ss.each do |s, ps| ps = if predicate.nil? || predicate.is_a?(RDF::Query::Variable) ps elsif ps.has_key?(predicate) { predicate => ps[predicate] } else [] end ps.each do |p, os| os.each do |o| next unless object.nil? || object.eql?(o) yield RDF::Statement.new(s, p, o, graph_name: c.equal?(DEFAULT_GRAPH) ? nil : c) end end end end else enum_for(:query_pattern, pattern, options) end end
Private Instance Methods
@private @return [Hamster::Hash] a new, updated hamster hash
# File lib/rdf/repository.rb, line 496 def delete_from(data, statement) if has_statement_in?(data, statement) s, p, o, g = statement.to_quad g = DEFAULT_GRAPH unless supports?(:graph_name) g ||= DEFAULT_GRAPH os = data[g][s][p].delete(o) ps = os.empty? ? data[g][s].delete(p) : data[g][s].put(p, os) ss = ps.empty? ? data[g].delete(s) : data[g].put(s, ps) return ss.empty? ? data.delete(g) : data.put(g, ss) end data end
@private @see has_statement
# File lib/rdf/repository.rb, line 462 def has_statement_in?(data, statement) s, p, o, g = statement.to_quad g ||= DEFAULT_GRAPH data.has_key?(g) && data[g].has_key?(s) && data[g][s].has_key?(p) && data[g][s][p].include?(o) end
@private @return [Hamster::Hash] a new, updated hamster hash
# File lib/rdf/repository.rb, line 475 def insert_to(data, statement) raise ArgumentError, "Statement #{statement.inspect} is incomplete" if statement.incomplete? unless has_statement_in?(data, statement) s, p, o, c = statement.to_quad c ||= DEFAULT_GRAPH return data.put(c) do |subs| subs = (subs || Hamster::Hash.new).put(s) do |preds| preds = (preds || Hamster::Hash.new).put(p) do |objs| (objs || Hamster::Set.new).add(o) end end end end data end