Class: RDF::Repository

Inherits:
Dataset show all
Includes:
Mutable, Transactable
Defined in:
lib/rdf/repository.rb

Overview

An RDF repository.

Repositories support transactions with a variety of ACID semantics:

Atomicity is indicated by #supports?(:atomic_write). When atomicity is supported, writes through #transaction, #apply_changeset and #delete_insert are applied atomically.

Consistency should be guaranteed, in general. Repositories that don't support consistency, or that have specialized definitions of consistency above those declared by the RDF data model, should advertise this fact in their documentation.

Isolation may be supported at various levels, indicated by #isolation_level:

  • :read_uncommitted: Inserts & deletes in an uncommitted transaction scope may be visible to other transactions (or via #each, etc...)
  • :read_committed: Inserts & deletes may be visible to other transactions once committed
  • :repeatable_read: Phantom reads may be possible
  • :snapshot: A transaction reads a consistent snapshot of the data. Write skew anomalies may occur (for various definitions of consistency)
  • :serializable: A transaction reads a consistent snapshot of the data. When two or more transactions attempt conflicting writes, only one of them may succeed.

Durability is noted via RDF::Durable support and #durable? /#nondurable?.

Examples:

Creating a transient in-memory repository

repository = RDF::Repository.new

Checking whether a repository is readable/writable

repository.readable?
repository.writable?

Checking whether a repository is persistent or transient

repository.persistent?
repository.transient?

Checking whether a repository is empty

repository.empty?

Checking how many statements a repository contains

repository.count

Checking whether a repository contains a specific statement

repository.has_statement?(statement)

Enumerating statements in a repository

repository.each_statement { |statement| statement.inspect! }

Inserting statements into a repository

repository.insert(*statements)
repository.insert(statement)
repository.insert([subject, predicate, object])
repository << statement
repository << [subject, predicate, object]

Deleting statements from a repository

repository.delete(*statements)
repository.delete(statement)
repository.delete([subject, predicate, object])

Deleting all statements from a repository

repository.clear!

Transational read from a repository

repository.transaction do |tx|
  tx.has_statement?(statement)
  tx.query([:s, :p, :o])
end

Transational read/write of a repository

repository.transaction(mutable: true) do |tx|
  tx.insert(*statements)
  tx.insert(statement)
  tx.insert([subject, predicate, object])
  tx.delete(*statements)
  tx.delete(statement)
  tx.delete([subject, predicate, object])
end

Defined Under Namespace

Modules: Implementation

Constant Summary

DEFAULT_TX_CLASS =
RDF::Transaction

Constants inherited from Dataset

Dataset::ISOLATION_LEVELS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Transactable

#commit_transaction, #rollback_transaction, #transaction

Methods included from Mutable

#<<, #apply_changeset, #clear, #delete, #delete_statement, #delete_statements, #immutable?, #insert, #load, #method_missing, #mutable?, #respond_to_missing?, #update

Methods included from Util::Aliasing::LateBound

#alias_method

Methods included from Writable

#<<, #insert, #insert_graph, #insert_reader, #insert_statement, #insert_statements, #writable?

Methods included from Readable

#readable?

Methods inherited from Dataset

#inspect, #inspect!

Methods included from Queryable

#first, #first_literal, #first_object, #first_predicate, #first_subject, #first_value, #query, #query_execute, #query_pattern

Methods included from Durable

#durable?, #nondurable?

Methods included from Enumerable

#dump, #each_graph, #each_object, #each_predicate, #each_quad, #each_statement, #each_subject, #each_term, #each_triple, #enum_graph, #enum_object, #enum_predicate, #enum_quad, #enum_statement, #enum_subject, #enum_term, #enum_triple, #graph_names, #has_graph?, #has_object?, #has_predicate?, #has_quad?, #has_statement?, #has_subject?, #has_term?, #has_triple?, #invalid?, #method_missing, #objects, #predicates, #quads, #respond_to_missing?, #statements, #subjects, #terms, #to_a, #to_hash, #to_set, #triples, #valid?, #validate!

Methods included from Countable

#count, #empty?

Constructor Details

#initialize(uri: nil, title: nil, **options) {|repository| ... } ⇒ Repository

Initializes this repository instance.

Parameters:

  • uri (URI, #to_s)

    (nil)

  • title (String, #to_s)

    (nil)

  • options (Hash{Symbol => Object})

Options Hash (**options):

  • :with_graph_name (Boolean) — default: true

    Indicates that the repository supports named graphs, otherwise, only the default graph is supported.

  • :with_validity (Boolean) — default: true

    Indicates that the repository supports named validation.

  • :transaction_class (Boolean) — default: DEFAULT_TX_CLASS

    Specifies the RDF::Transaction implementation to use in this Repository.

Yields:

  • (repository)

Yield Parameters:



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/rdf/repository.rb', line 151

def initialize(uri: nil, title: nil, **options, &block)
  @options = {with_graph_name: true, with_validity: true}.merge(options)
  @uri     = uri
  @title   = title

  # Provide a default in-memory implementation:
  send(:extend, Implementation) if self.class.equal?(RDF::Repository)

  @tx_class ||= @options.delete(:transaction_class) { DEFAULT_TX_CLASS }

  if block_given?
    case block.arity
      when 1 then block.call(self)
      else instance_eval(&block)
    end
  end
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class RDF::Mutable

Instance Attribute Details

#optionsHash{Symbol => Object} (readonly)

Returns the options passed to this repository when it was constructed.

Returns:

  • (Hash{Symbol => Object})


97
98
99
# File 'lib/rdf/repository.rb', line 97

def options
  @options
end

#titleString (readonly)

Returns the title of this repository.

Returns:

  • (String)


110
111
112
# File 'lib/rdf/repository.rb', line 110

def title
  @title
end

#uriURI (readonly) Also known as: url

Returns the URI of this repository.

Returns:



103
104
105
# File 'lib/rdf/repository.rb', line 103

def uri
  @uri
end

Class Method Details

.load(urls, options = {}) {|repository| ... }

This method returns an undefined value.

Loads one or more RDF files into a new transient in-memory repository.

Parameters:

  • urls (String, Array<String>)
  • options (Hash{Symbol => Object}) (defaults to: {})

    Options from #initialize and Mutable#load

Yields:

  • (repository)

Yield Parameters:



121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/rdf/repository.rb', line 121

def self.load(urls, options = {}, &block)
  self.new(options) do |repository|
    Array(urls).each do |url|
      repository.load(url, options)
    end

    if block_given?
      case block.arity
        when 1 then block.call(repository)
        else repository.instance_eval(&block)
      end
    end
  end
end

Instance Method Details

#delete_insert(deletes, inserts) ⇒ Object

Performs a set of deletes and inserts as a combined operation within a transaction. The Repository's transaction semantics apply to updates made through this method.



195
196
197
198
199
200
201
202
# File 'lib/rdf/repository.rb', line 195

def delete_insert(deletes, inserts)
  return super unless supports?(:atomic_write)

  transaction(mutable: true) do
    deletes.respond_to?(:each_statement) ? delete(deletes) : delete(*deletes)
    inserts.respond_to?(:each_statement) ? insert(inserts) : insert(*inserts)
  end
end

#isolation_levelObject



214
215
216
# File 'lib/rdf/repository.rb', line 214

def isolation_level
  supports?(:snapshot) ? :repeatable_read : super
end

#snapshotDataset

A queryable snapshot of the repository for isolated reads.

Returns:

  • (Dataset)

    an immutable Dataset containing a current snapshot of the Repository contents.

Raises:

  • (NotImplementedError)


223
224
225
# File 'lib/rdf/repository.rb', line 223

def snapshot
  raise NotImplementedError.new("#{self.class}#snapshot")
end

#supports?(feature) ⇒ Boolean

Returns true if this respository supports the given feature.

Supported features include those from Enumerable#supports? along with the following:

  • :atomic_write supports atomic write in transaction scopes
  • :snapshots supports creation of immutable snapshots of current contents via #snapshot.

Returns:

  • (Boolean)

See Also:



178
179
180
181
182
183
184
185
186
187
# File 'lib/rdf/repository.rb', line 178

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 false
  when :snapshots    then false
  else false
  end
end