class RDF::Mongo::Repository

Attributes

client[R]

The Mongo database instance @return [Mongo::DB]

collection[R]

The collection used for storing quads @return [Mongo::Collection]

Public Class Methods

new(**options, &block) click to toggle source

Initializes this repository instance.

@overload initialize(**options, &block)

@param  [Hash{Symbol => Object}] options
@option options [String, #to_s] :title (nil)
@option options [URI, #to_s]    :uri (nil)
  URI in the form `mongodb://host:port/db`. The URI should also identify the collection use, but appending a `collection` path component such as `mongodb://host:port/db/collection`, this ensures that the collection will be maintained if cloned. See [Mongo::Client options](https://docs.mongodb.org/ecosystem/tutorial/ruby-driver-tutorial-2-0/#uri-options-conversions) for more information on Mongo URIs.

@overload initialize(**options, &block)

@param  [Hash{Symbol => Object}] options
  See [Mongo::Client options](https://docs.mongodb.org/ecosystem/tutorial/ruby-driver-tutorial-2-0/#uri-options-conversions) for more information on Mongo Client options.
@option options [String, #to_s] :title (nil)
@option options [String] :host
  a single address or an array of addresses, which may contain a port designation
@option options [Integer] :port (27017) applied to host address(es)
@option options [String] :database ('quadb')
@option options [String] :collection ('quads')

@yield [repository] @yieldparam [Repository] repository

Calls superclass method
# File lib/rdf/mongo.rb, line 139
def initialize(**options, &block)
  collection = nil
  if options[:uri]
    options = options.dup
    uri = RDF::URI(options.delete(:uri))
    _, db, coll = uri.path.split('/')
    collection = coll || options.delete(:collection)
    db ||= "quadb"
    uri.path = "/#{db}" if coll
    @client = ::Mongo::Client.new(uri.to_s, **options)
  else
    warn "[DEPRECATION] RDF::Mongo::Repository#initialize expects a uri argument. Called from #{Gem.location_of_caller.join(':')}" unless options.empty?
    options[:database] ||= options.delete(:db) # 1.x compat
    options[:database] ||= 'quadb'
    hosts = Array(options[:host] || 'localhost')
    hosts.map! {|h| "#{h}:#{options[:port]}"} if options[:port]
    @client = ::Mongo::Client.new(hosts, **options)
  end

  @collection = @client[options.delete(:collection) || 'quads']
  @collection.indexes.create_many([
    {key: {s: 1}},
    {key: {p: 1}},
    {key: {o: "hashed"}},
    {key: {c: 1}},
    {key: {s: 1, p: 1}},
    #{key: {s: 1, o: "hashed"}}, # Muti-key hashed indexes not allowed
    #{key: {p: 1, o: "hashed"}}, # Muti-key hashed indexes not allowed
  ])
  super(**options, &block)
end

Public Instance Methods

apply_changeset(changeset) click to toggle source
# File lib/rdf/mongo.rb, line 182
def apply_changeset(changeset)
  ops = []

  changeset.deletes.each do |d|
    ops << { delete_one: { filter: statement_to_delete(d)} }
  end

  changeset.inserts.each do |i|
    ops << { update_one: { filter: statement_to_insert(i), update: statement_to_insert(i), upsert: true} }
  end

  @collection.bulk_write(ops, ordered: true)
end
clear_statements() click to toggle source
# File lib/rdf/mongo.rb, line 224
def clear_statements
  @collection.delete_many
end
count() click to toggle source

@private @see RDF::Countable#count

# File lib/rdf/mongo.rb, line 220
def count
  @collection.count
end
delete_statement(statement) click to toggle source

@see RDF::Mutable#delete_statement

# File lib/rdf/mongo.rb, line 202
def delete_statement(statement)
  st_mongo = statement_to_delete(statement)
  @collection.delete_one(st_mongo)
end
durable?() click to toggle source

@private @see RDF::Durable#durable?

# File lib/rdf/mongo.rb, line 210
def durable?; true; end
each(&block)
Alias for: each_statement
each_statement(&block) click to toggle source

@private @see RDF::Enumerable#each_statement

# File lib/rdf/mongo.rb, line 237
def each_statement(&block)
  @nodes = {} # reset cache. FIXME this should probably be in Node.intern
  if block_given?
    @collection.find().each do |document|
      block.call(RDF::Statement.from_mongo(document))
    end
  end
  enum_statement
end
Also aliased as: each
empty?() click to toggle source

@private @see RDF::Countable#empty?

# File lib/rdf/mongo.rb, line 215
def empty?; @collection.count == 0; end
has_graph?(value) click to toggle source

@private @see RDF::Enumerable#has_graph?

# File lib/rdf/mongo.rb, line 251
def has_graph?(value)
  @collection.find(RDF::Mongo::Conversion.to_mongo(value, :graph_name)).count > 0
end
has_statement?(statement) click to toggle source

@private @see RDF::Enumerable#has_statement?

# File lib/rdf/mongo.rb, line 231
def has_statement?(statement)
  @collection.find(statement.to_mongo).count > 0
end
insert_statement(statement) click to toggle source
# File lib/rdf/mongo.rb, line 196
def insert_statement(statement)
  st_mongo = statement_to_insert(statement)
  @collection.update_one(st_mongo, st_mongo, upsert: true)
end
supports?(feature) click to toggle source

@see RDF::Mutable#insert_statement

# File lib/rdf/mongo.rb, line 172
def supports?(feature)
  case feature.to_sym
    when :graph_name        then true
    when :atomic_write      then true
    when :validity          then @options.fetch(:with_validity, true)
    when :literal_equality  then true
    else false
  end
end

Protected Instance Methods

query_pattern(pattern, **options, &block) click to toggle source

@private @see RDF::Queryable#query_pattern @see RDF::Query::Pattern

# File lib/rdf/mongo.rb, line 261
def query_pattern(pattern, **options, &block)
  return enum_for(:query_pattern, pattern, **options) unless block_given?
  @nodes = {} # reset cache. FIXME this should probably be in Node.intern

  # A pattern graph_name of `false` is used to indicate the default graph
  pm = pattern.to_mongo
  pm.merge!(c: nil, ct: :default) if pattern.graph_name == false
  #puts "query using #{pm.inspect}"
  @collection.find(pm).each do |document|
    block.call(RDF::Statement.from_mongo(document))
  end
end

Private Instance Methods

enumerator!() click to toggle source
# File lib/rdf/mongo.rb, line 276
def enumerator! # @private
  require 'enumerator' unless defined?(::Enumerable)
  @@enumerator_klass = defined?(::Enumerable::Enumerator) ? ::Enumerable::Enumerator : ::Enumerator
end
statement_to_delete(statement) click to toggle source
# File lib/rdf/mongo.rb, line 289
def statement_to_delete(statement)
  st_mongo = statement.to_mongo
  st_mongo[:ct] = :default if statement.graph_name.nil?
  st_mongo
end
statement_to_insert(statement) click to toggle source
# File lib/rdf/mongo.rb, line 281
def statement_to_insert(statement)
  raise ArgumentError, "Statement #{statement.inspect} is incomplete" if statement.incomplete?
  st_mongo = statement.to_mongo
  st_mongo[:ct] ||= :default # Indicate statement is in the default graph
  #puts "insert statement: #{st_mongo.inspect}"
  st_mongo
end