Module: RDF::Mutable

Extended by:
Util::Aliasing::LateBound
Includes:
Readable, Util::Coercions, Writable
Included in:
Graph, Repository, Transaction
Defined in:
lib/rdf/mixin/mutable.rb

Overview

Classes that include this module must implement the methods #insert_statement, #delete_statement and #each_statement.

See Also:

Instance Method Summary collapse

Methods included from Util::Aliasing::LateBound

alias_method

Methods included from Util::Coercions

#coerce_statements

Methods included from Writable

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

Methods included from Readable

#readable?

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#String

Implements #from_reader for each available instance of Reader, based on the reader symbol.

Arguments are passed to Reader.new.

Returns:

  • (String)

See Also:

  • RDF::Mutable.{RDF{RDF::Reader{RDF::Reader.sym}


245
246
247
248
249
250
251
252
# File 'lib/rdf/mixin/mutable.rb', line 245

def method_missing(meth, *args)
  reader = RDF::Reader.for(meth.to_s[5..-1].to_sym) if meth.to_s[0,5] == "from_"
  if reader
    self << reader.new(*args)
  else
    super
  end
end

Instance Method Details

#<<(data) ⇒ Mutable

Inserts RDF data into self.

Parameters:

Returns:

Raises:

  • (TypeError)

    if self is immutable

See Also:



69
70
71
72
73
# File 'lib/rdf/mixin/mutable.rb', line 69

def <<(data)
  raise TypeError.new("#{self} is immutable") if immutable?

  super # RDF::Writable#<<
end

#apply_changeset(changeset) ⇒ Boolean

Applies the given changeset

If #supports?(:atomic_write) is true, this must apply the changeset atomically. Otherwise, it should offer an efficient implementation of a combined delete/insert of the changeset.

Parameters:

Returns:

  • (Boolean)

    true if the changeset has been applied



200
201
202
# File 'lib/rdf/mixin/mutable.rb', line 200

def apply_changeset(changeset)
  delete_insert(changeset.deletes, changeset.inserts)
end

#clearMutable Also known as: clear!

Deletes all RDF statements from self.

Returns:

Raises:

  • (TypeError)

    if self is immutable



222
223
224
225
226
227
228
229
230
231
232
# File 'lib/rdf/mixin/mutable.rb', line 222

def clear
  raise TypeError.new("#{self} is immutable") if immutable?

  if respond_to?(:clear_statements, true)
    clear_statements
  else
    delete_statements(self)
  end

  return self
end

#delete(*statements) ⇒ self #delete(statements) ⇒ self Also known as: delete!

Note:

using splat argument syntax with excessive arguments provided

Deletes RDF statements from self. If any statement contains a Query::Variable, it is considered to be a pattern, and used to query self to find matching statements to delete.

significantly affects performance. Use Enumerator form for large numbers of statements.

Overloads:

  • #delete(*statements) ⇒ self

    Parameters:

    Returns:

    • (self)

    Raises:

    • (TypeError)

      if self is immutable

  • #delete(statements) ⇒ self

    Parameters:

    Returns:

    • (self)

    Raises:

    • (TypeError)

      if self is immutable

Raises:

  • (TypeError)


155
156
157
158
159
160
161
162
163
# File 'lib/rdf/mixin/mutable.rb', line 155

def delete(*statements)
  raise TypeError.new("#{self} is immutable") if immutable?

  coerce_statements(statements, query: true, constant: true) do |value|
    delete_statements(value)
  end

  return self
end

#delete_insert(deletes, inserts) ⇒ Mutable Also known as: delete_insert!

Note:

in the base implementation, this is equivalent to calling #delete and #insert sequentially. This method is preferred to take advantage of (e.g.) RDF::Repositories that can execute the operation in a single request.

Performs a set of deletes and inserts as a combined operation.

Parameters:

Returns:

Raises:

  • (TypeError)

    if self is immutable

See Also:



182
183
184
185
186
187
# File 'lib/rdf/mixin/mutable.rb', line 182

def delete_insert(deletes, inserts)
  deletes.respond_to?(:each_statement) ? delete(deletes) : delete(*deletes)
  inserts.respond_to?(:each_statement) ? insert(inserts) : insert(*inserts)

  self
end

#delete_statement(statement) (protected)

This method is abstract.

This method returns an undefined value.

Deletes an RDF statement from the underlying storage.

Subclasses of Repository must implement this method, except if they are immutable.

Parameters:

Raises:

  • (NotImplementedError)


292
293
294
# File 'lib/rdf/mixin/mutable.rb', line 292

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

#delete_statements(statements) (protected)

This method returns an undefined value.

Deletes the given RDF statements from the underlying storage.

Defaults to invoking #delete_statement for each given statement.

Subclasses of Repository may wish to override this method if they are capable of more efficiently deleting multiple statements at once.

Parameters:



276
277
278
279
280
281
# File 'lib/rdf/mixin/mutable.rb', line 276

def delete_statements(statements)
  each = statements.respond_to?(:each_statement) ? :each_statement : :each
  statements.__send__(each) do |statement|
    delete_statement(statement)
  end
end

#immutable?Boolean

Returns true if self is immutable.

Returns:

  • (Boolean)

See Also:



28
29
30
# File 'lib/rdf/mixin/mutable.rb', line 28

def immutable?
  !mutable?
end

#insert(*statements) ⇒ self #insert(statements) ⇒ self

Note:

using splat argument syntax with excessive arguments provided

Inserts RDF statements into self.

significantly affects performance. Use Enumerator form for large numbers of statements.

Overloads:

  • #insert(*statements) ⇒ self

    Parameters:

    Returns:

    • (self)

    Raises:

    • (TypeError)

      if self is immutable

  • #insert(statements) ⇒ self

    Parameters:

    Returns:

    • (self)

    Raises:

    • (TypeError)

      if self is immutable

Raises:

  • (TypeError)

See Also:



93
94
95
96
97
# File 'lib/rdf/mixin/mutable.rb', line 93

def insert(*statements)
  raise TypeError.new("#{self} is immutable") if immutable?

  super # RDF::Writable#insert
end

#load(url, graph_name: nil, **options) Also known as: load!

This method returns an undefined value.

Loads RDF statements from the given file or URL into self.

Parameters:

  • url (String, #to_s)
  • options (Hash{Symbol => Object})

    Options from Reader.open

Options Hash (**options):

  • :graph_name (RDF::Resource)

    Set set graph name of each loaded statement

Raises:

  • (TypeError)


41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/rdf/mixin/mutable.rb', line 41

def load(url, graph_name: nil, **options)
  raise TypeError.new("#{self} is immutable") if immutable?

  Reader.open(url, base_uri: url, **options) do |reader|
    if graph_name
      statements = []
      reader.each_statement do |statement|
        statement.graph_name = graph_name
        statements << statement
      end
      insert_statements(statements)
      statements.size
    else
      insert_statements(reader)
      nil
    end
  end
end

#mutable?Boolean

Returns true if self is mutable.

Returns:

  • (Boolean)

See Also:



19
20
21
# File 'lib/rdf/mixin/mutable.rb', line 19

def mutable?
  writable?
end

#respond_to_missing?(name, include_private = false) ⇒ Boolean

Note:

this instantiates an entire reader; it could probably be done more efficiently by refactoring RDF::Reader and/or RDF::Format to expose a list of valid format symbols.

Returns:

  • (Boolean)


258
259
260
261
# File 'lib/rdf/mixin/mutable.rb', line 258

def respond_to_missing?(name, include_private = false)
  return RDF::Reader.for(name.to_s[5..-1].to_sym) if name.to_s[0,5] == 'from_'
  super 
end

#snapshotDataset

A readable & queryable snapshot of the repository for isolated reads.

This method must be implemented when #supports(:snapshots) is true.

Returns:

  • (Dataset)

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

Raises:

  • (NotImplementederror)

    when snapshots aren't implemented for the class



213
214
215
# File 'lib/rdf/mixin/mutable.rb', line 213

def snapshot
  raise NotImplementedError, "#{self.class} does not implement snapshots"
end

#update(*statements) ⇒ self #update(statements) ⇒ self Also known as: update!

Note:

using splat argument syntax with excessive arguments provided

Updates RDF statements in self.

#update([subject, predicate, object]) is equivalent to #delete([subject, predicate, nil]) followed by #insert([subject, predicate, object]) unless object is nil.

significantly affects performance. Use Enumerator form for large numbers of statements.

Overloads:

  • #update(*statements) ⇒ self

    Parameters:

    Returns:

    • (self)

    Raises:

    • (TypeError)

      if self is immutable

  • #update(statements) ⇒ self

    Parameters:

    Returns:

    • (self)

    Raises:

    • (TypeError)

      if self is immutable

Raises:

  • (TypeError)


119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/rdf/mixin/mutable.rb', line 119

def update(*statements)
  raise TypeError.new("#{self} is immutable") if immutable?
  statements = statements[0] if statements.length == 1 && statements[0].is_a?(Enumerable)

  statements.each do |statement|
    if (statement = Statement.from(statement))
      if statement.object?
        delete_insert([[statement.subject, statement.predicate, nil]], [statement])
      else
        delete([statement.subject, statement.predicate, nil])
      end
    end
  end
end