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 Transactable#transaction, Mutable#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 Durable support and Dataset#durable? /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.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.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 collapse

DEFAULT_TX_CLASS =
RDF::Transaction

Constants inherited from Dataset

Dataset::DEFAULT_GRAPH, Dataset::ISOLATION_LEVELS

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Transactable

#transaction

Methods included from Mutable

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

Methods included from Util::Aliasing::LateBound

#alias_method

Methods included from Writable

#<<, #insert, #writable?

Methods included from Readable

#readable?

Methods inherited from Dataset

#durable?, #each, #inspect, #inspect!

Methods included from Queryable

#enum_for, #first, #first_literal, #first_object, #first_predicate, #first_subject, #first_value, #query

Methods included from Durable

#durable?, #nondurable?

Methods included from Enumerable

#canonicalize, #canonicalize!, #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?, #graph_names, #invalid?, #object?, #objects, #predicate?, #predicates, #quad?, #quads, #statement?, #statements, #subject?, #subjects, #term?, #terms, #to_a, #to_h, #to_set, #triple?, #triples, #valid?, #validate!

Methods included from Countable

#count, #empty?, #enum_for

Constructor Details

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

Initializes this repository instance.

Parameters:

  • uri (URI, #to_s) (defaults to: nil)

    (nil)

  • title (String, #to_s) (defaults to: nil)

    (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| ... } ⇒ void

This method returns an undefined value.

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

Parameters:

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.



200
201
202
203
204
205
206
207
# File 'lib/rdf/repository.rb', line 200

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



220
221
222
# File 'lib/rdf/repository.rb', line 220

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

#project_graph(graph_name, &block) ⇒ Object



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

def project_graph(graph_name, &block)
  graph = RDF::Graph.new(graph_name: graph_name, data: self)
  graph.each(&block) if block_given?
  graph
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)


229
230
231
# File 'lib/rdf/repository.rb', line 229

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
188
189
190
191
192
# 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 :literal_equality then true
  when :atomic_write     then false
  when :rdf_full         then false
  # FIXME: quoted triples are now deprecated
  when :quoted_triples   then false
  when :base_direction   then false
  when :snapshots        then false
  else false
  end
end