class Mongo::DB

A MongoDB database.

Constants

SYSTEM_COMMAND_COLLECTION
SYSTEM_INDEX_COLLECTION
SYSTEM_JS_COLLECTION
SYSTEM_NAMESPACE_COLLECTION
SYSTEM_PROFILE_COLLECTION
SYSTEM_USER_COLLECTION

Attributes

cache_time[RW]

The length of time that Mongo::Collection#ensure_index should cache index calls

connection[R]

The Mongo::Connection instance connecting to the MongoDB server.

name[R]

The name of the database and the local safe option.

safe[R]

The name of the database and the local safe option.

strict[W]

Strict mode enforces collection existence checks. When true, asking for a collection that does not exist, or trying to create a collection that already exists, raises an error.

Strict mode is disabled by default, but enabled (true) at any time.

Public Class Methods

new(name, connection, opts={}) click to toggle source

Instances of DB are normally obtained by calling Mongo#db.

@param [String] name the database name. @param [Mongo::Connection] connection a connection object pointing to MongoDB. Note

that databases are usually instantiated via the Connection class. See the examples below.

@option opts [Boolean] :strict (False) If true, collections must exist to be accessed and must

not exist to be created. See DB#collection and DB#create_collection.

@option opts [Object, create_pk(doc)] :pk (BSON::ObjectId) A primary key factory object,

which should take a hash and return a hash which merges the original hash with any primary key
fields the factory wishes to inject. (NOTE: if the object already has a primary key,
the factory should not inject a new key).

@option opts [Boolean, Hash] :safe (false) Set the default safe-mode options

propagated to Collection objects instantiated off of this DB. If no
value is provided, the default value set on this instance's Connection object will be used. This
default can be overridden upon instantiation of any collection by explicity setting a :safe value
on initialization

@option opts [Integer] :cache_time (300) Set the time that all ensure_index calls should cache the command.

@core databases constructor_details

# File lib/mongo/db.rb, line 77
def initialize(name, connection, opts={})
  @name       = Mongo::Support.validate_db_name(name)
  @connection = connection
  @strict     = opts[:strict]
  @pk_factory = opts[:pk]
  @safe       = opts.fetch(:safe, @connection.safe)
  if value = opts[:read]
    Mongo::Support.validate_read_preference(value)
  else
    value = @connection.read_preference
  end
  @read_preference = value.is_a?(Hash) ? value.dup : value
  @cache_time = opts[:cache_time] || 300 #5 minutes.
end

Public Instance Methods

[](name, opts={})
Alias for: collection
add_stored_function(function_name, code) click to toggle source

Adds a stored Javascript function to the database which can executed

server-side in map_reduce, db.eval and $where clauses.

@param [String] function_name @param [String] code

@return [String] the function name saved to the database

# File lib/mongo/db.rb, line 149
def add_stored_function(function_name, code)
  self[SYSTEM_JS_COLLECTION].save(
    {
      "_id" => function_name, 
      :value => BSON::Code.new(code)
    }
  )
end
add_user(username, password, read_only = false) click to toggle source

Adds a user to this database for use with authentication. If the user already exists in the system, the password will be updated.

@param [String] username @param [String] password @param [Boolean] read_only

Create a read-only user.

@return [Hash] an object representing the user.

# File lib/mongo/db.rb, line 181
def add_user(username, password, read_only = false)
  users = self[SYSTEM_USER_COLLECTION]
  user  = users.find_one({:user => username}) || {:user => username}
  user['pwd'] = Mongo::Support.hash_password(username, password)
  user['readOnly'] = true if read_only;
  users.save(user)
  return user
end
authenticate(username, password, save_auth=true) click to toggle source

Authenticate with the given username and password. Note that mongod must be started with the –auth option for authentication to be enabled.

@param [String] username @param [String] password @param [Boolean] save_auth

Save this authentication to the connection object using Connection#add_auth. This
will ensure that the authentication will be applied on database reconnect. Note
that this value must be true when using connection pooling.

@return [Boolean]

@raise [AuthenticationError]

@core authenticate authenticate-instance_method

# File lib/mongo/db.rb, line 107
def authenticate(username, password, save_auth=true)
  if @connection.pool_size > 1
    if !save_auth
      raise MongoArgumentError, "If using connection pooling, :save_auth must be set to true."
    end
  end

  @connection.best_available_socket do |socket|
    issue_authentication(username, password, save_auth, :socket => socket)
  end

  @connection.authenticate_pools
end
collection(name, opts={}) click to toggle source

Get a collection by name.

@param [String, Symbol] name the collection name. @param [Hash] opts any valid options that can be passed to Collection#new.

@raise [MongoDBError] if collection does not already exist and we're in

+strict+ mode.

@return [Mongo::Collection]

# File lib/mongo/db.rb, line 310
def collection(name, opts={})
  if strict? && !collection_names.include?(name.to_s)
    raise Mongo::MongoDBError, "Collection #{name} doesn't exist. " +
      "Currently in strict mode."
  else
    opts = opts.dup
    opts[:safe] = opts.fetch(:safe, @safe)
    opts.merge!(:pk => @pk_factory) unless opts[:pk]
    Collection.new(name, self, opts)
  end
end
Also aliased as: []
collection_names() click to toggle source

Get an array of collection names in this database.

@return [Array]

# File lib/mongo/db.rb, line 232
def collection_names
  names = collections_info.collect { |doc| doc['name'] || '' }
  names = names.delete_if {|name| name.index(@name).nil? || name.index('$')}
  names.map {|name| name.sub(@name + '.', '')}
end
collections() click to toggle source

Get an array of Collection instances, one for each collection in this database.

@return [Array<Mongo::Collection>]

# File lib/mongo/db.rb, line 241
def collections
  collection_names.map do |name|
    Collection.new(name, self)
  end
end
collections_info(coll_name=nil) click to toggle source

Get info on system namespaces (collections). This method returns a cursor which can be iterated over. For each collection, a hash will be yielded containing a 'name' string and, optionally, an 'options' hash.

@param [String] coll_name return info for the specifed collection only.

@return [Mongo::Cursor]

# File lib/mongo/db.rb, line 254
def collections_info(coll_name=nil)
  selector = {}
  selector[:name] = full_collection_name(coll_name) if coll_name
  Cursor.new(Collection.new(SYSTEM_NAMESPACE_COLLECTION, self), :selector => selector)
end
command(selector, opts={}) click to toggle source

Send a command to the database.

Note: DB commands must start with the “command” key. For this reason, any selector containing more than one key must be an OrderedHash.

Note also that a command in MongoDB is just a kind of query that occurs on the system command collection ($cmd). Examine this method's implementation to see how it works.

@param [OrderedHash, Hash] selector an OrderedHash, or a standard Hash with just one key, specifying the command to be performed. In Ruby 1.9, OrderedHash isn't necessary since hashes are ordered by default.

@option opts [Boolean] :check_response (true) If true, raises an exception if the command fails. @option opts [Socket] :socket a socket to use for sending the command. This is mainly for internal use.

@return [Hash]

@core commands command_instance-method

# File lib/mongo/db.rb, line 501
def command(selector, opts={})
  check_response = opts.fetch(:check_response, true)
  socket         = opts[:socket]
  raise MongoArgumentError, "command must be given a selector" unless selector.is_a?(Hash) && !selector.empty?
  if selector.keys.length > 1 && RUBY_VERSION < '1.9' && selector.class != BSON::OrderedHash
    raise MongoArgumentError, "DB#command requires an OrderedHash when hash contains multiple keys"
  end

  begin
    result = Cursor.new(system_command_collection,
      :limit => -1, :selector => selector, :socket => socket).next_document
  rescue OperationFailure => ex
    raise OperationFailure, "Database command '#{selector.keys.first}' failed: #{ex.message}"
  end

  if result.nil?
    raise OperationFailure, "Database command '#{selector.keys.first}' failed: returned null."
  elsif (check_response && !ok?(result))
    message = "Database command '#{selector.keys.first}' failed: ("
    message << result.map do |key, value|
      "#{key}: '#{value}'"
    end.join('; ')
    message << ').'
    code = result['code'] || result['assertionCode']
    raise OperationFailure.new(message, code, result)
  else
    result
  end
end
create_collection(name, opts={}) click to toggle source

Create a collection.

new collection. If strict is true, will raise an error if collection name already exists.

@param [String, Symbol] name the name of the new collection.

@option opts [Boolean] :capped (False) created a capped collection.

@option opts [Integer] :size (Nil) If capped is true,

specifies the maximum number of bytes for the capped collection.
If +false+, specifies the number of bytes allocated
for the initial extent of the collection.

@option opts [Integer] :max (Nil) If capped is true, indicates

the maximum number of records in a capped collection.

@raise [MongoDBError] raised under two conditions:

either we're in +strict+ mode and the collection
already exists or collection creation fails on the server.

@return [Mongo::Collection]

# File lib/mongo/db.rb, line 282
def create_collection(name, opts={})
  name = name.to_s
  if collection_names.include?(name)
    if strict?
      raise MongoDBError, "Collection #{name} already exists. " +
        "Currently in strict mode."
    else
      return Collection.new(name, self, opts)
    end
  end

  # Create a new collection.
  oh = BSON::OrderedHash.new
  oh[:create] = name
  doc = command(oh.merge(opts || {}))
  return Collection.new(name, self, :pk => @pk_factory) if ok?(doc)
  raise MongoDBError, "Error creating collection: #{doc.inspect}"
end
dereference(dbref) click to toggle source

Dereference a DBRef, returning the document it points to.

@param [Mongo::DBRef] dbref

@return [Hash] the document indicated by the db reference.

@see www.mongodb.org/display/DOCS/DB+Ref MongoDB DBRef spec.

# File lib/mongo/db.rb, line 393
def dereference(dbref)
  collection(dbref.namespace).find_one("_id" => dbref.object_id)
end
drop_collection(name) click to toggle source

Drop a collection by name.

@param [String, Symbol] name

@return [Boolean] true on success or false if the collection name doesn't exist.

# File lib/mongo/db.rb, line 328
def drop_collection(name)
  return true unless collection_names.include?(name.to_s)

  ok?(command(:drop => name))
end
drop_index(collection_name, index_name) click to toggle source

Drop an index from a given collection. Normally called from Mongo::Collection#drop_index or Mongo::Collection#drop_indexes.

@param [String] collection_name @param [String] index_name

@return [True] returns true on success.

@raise MongoDBError if there's an error dropping the index.

# File lib/mongo/db.rb, line 441
def drop_index(collection_name, index_name)
  oh = BSON::OrderedHash.new
  oh[:deleteIndexes] = collection_name
  oh[:index] = index_name.to_s
  doc = command(oh, :check_response => false)
  ok?(doc) || raise(MongoDBError, "Error with drop_index command: #{doc.inspect}")
end
error?() click to toggle source

Return true if an error was caused by the most recently executed database operation.

@return [Boolean]

# File lib/mongo/db.rb, line 357
def error?
  get_last_error['err'] != nil
end
eval(code, *args) click to toggle source

Evaluate a JavaScript expression in MongoDB.

@param [String, Code] code a JavaScript expression to evaluate server-side. @param [Integer, Hash] args any additional argument to be passed to the code expression when

it's run on the server.

@return [String] the return value of the function.

# File lib/mongo/db.rb, line 404
def eval(code, *args)
  if not code.is_a? BSON::Code
    code = BSON::Code.new(code)
  end

  oh = BSON::OrderedHash.new
  oh[:$eval] = code
  oh[:args]  = args
  doc = command(oh)
  doc['retval']
end
full_collection_name(collection_name) click to toggle source

A shortcut returning db plus dot plus collection name.

@param [String] collection_name

@return [String]

# File lib/mongo/db.rb, line 536
def full_collection_name(collection_name)
  "#{@name}.#{collection_name}"
end
get_last_error(opts={}) click to toggle source

Run the getlasterror command with the specified replication options.

@option opts [Boolean] :fsync (false) @option opts [Integer] :w (nil) @option opts [Integer] :wtimeout (nil) @option opts [Boolean] :j (false)

@return [Hash] the entire response to getlasterror.

@raise [MongoDBError] if the operation fails.

# File lib/mongo/db.rb, line 344
def get_last_error(opts={})
  cmd = BSON::OrderedHash.new
  cmd[:getlasterror] = 1
  cmd.merge!(opts)
  doc = command(cmd, :check_response => false)
  raise MongoDBError, "error retrieving last error: #{doc.inspect}" unless ok?(doc)
  doc
end
index_information(collection_name) click to toggle source

Get information on the indexes for the given collection. Normally called by Mongo::Collection#index_information.

@param [String] collection_name

@return [Hash] keys are index names and the values are lists of [key, direction] pairs

defining the index.
# File lib/mongo/db.rb, line 456
def index_information(collection_name)
  sel  = {:ns => full_collection_name(collection_name)}
  info = {}
  Cursor.new(Collection.new(SYSTEM_INDEX_COLLECTION, self), :selector => sel).each do |index|
    info[index['name']] = index
  end
  info
end
issue_authentication(username, password, save_auth=true, opts={}) click to toggle source
# File lib/mongo/db.rb, line 121
def issue_authentication(username, password, save_auth=true, opts={})
  doc = command({:getnonce => 1}, :check_response => false, :socket => opts[:socket])
  raise MongoDBError, "Error retrieving nonce: #{doc}" unless ok?(doc)
  nonce = doc['nonce']

  auth = BSON::OrderedHash.new
  auth['authenticate'] = 1
  auth['user'] = username
  auth['nonce'] = nonce
  auth['key'] = Mongo::Support.auth_key(username, password, nonce)
  if ok?(doc = self.command(auth, :check_response => false, :socket => opts[:socket]))
    if save_auth
      @connection.add_auth(@name, username, password)
    end
    true
  else
    message = "Failed to authenticate user '#{username}' on db '#{self.name}'"
    raise Mongo::AuthenticationError.new(message, doc['code'], doc)
  end
end
issue_logout(opts={}) click to toggle source
# File lib/mongo/db.rb, line 219
def issue_logout(opts={})
  doc = command({:logout => 1}, :socket => opts[:socket])
  if ok?(doc)
    @connection.remove_auth(@name)
    true
  else
    raise MongoDBError, "error logging out: #{doc.inspect}"
  end
end
logout(opts={}) click to toggle source

Deauthorizes use for this database for this connection. Also removes any saved authentication in the connection class associated with this database.

@raise [MongoDBError] if logging out fails.

@return [Boolean]

# File lib/mongo/db.rb, line 211
def logout(opts={})
  if @connection.pool_size > 1
    @connection.logout_pools(@name)
  end

  issue_logout(opts)
end
ok?(doc) click to toggle source

Return true if the supplied doc contains an 'ok' field with the value 1.

@param [Hash] doc

@return [Boolean]

# File lib/mongo/db.rb, line 477
def ok?(doc)
  Mongo::Support.ok?(doc)
end
pk_factory() click to toggle source

The primary key factory object (or nil).

@return [Object, Nil]

# File lib/mongo/db.rb, line 543
def pk_factory
  @pk_factory
end
pk_factory=(pk_factory) click to toggle source

Specify a primary key factory if not already set.

@raise [MongoArgumentError] if the primary key factory has already been set.

# File lib/mongo/db.rb, line 550
def pk_factory=(pk_factory)
  if @pk_factory
    raise MongoArgumentError, "Cannot change primary key factory once it's been set"
  end

  @pk_factory = pk_factory
end
previous_error() click to toggle source

Get the most recent error to have occured on this database.

This command only returns errors that have occured since the last call to #reset_error_history - returns nil if there is no such error.

@return [String, Nil] the text of the error or nil if no error has occurred.

# File lib/mongo/db.rb, line 367
def previous_error
  error = command(:getpreverror => 1)
  if error["err"]
    error
  else
    nil
  end
end
profiling_info() click to toggle source

Get the current profiling information.

@return [Array] a list of documents containing profiling information.

# File lib/mongo/db.rb, line 604
def profiling_info
  Cursor.new(Collection.new(SYSTEM_PROFILE_COLLECTION, self), :selector => {}).to_a
end
profiling_level() click to toggle source

Return the current database profiling level. If profiling is enabled, you can get the results using #profiling_info.

@return [Symbol] :off, :slow_only, or :all

@core profiling profiling_level-instance_method

# File lib/mongo/db.rb, line 564
def profiling_level
  oh = BSON::OrderedHash.new
  oh[:profile] = -1
  doc = command(oh, :check_response => false)
  raise "Error with profile command: #{doc.inspect}" unless ok?(doc) && doc['was'].kind_of?(Numeric)
  case doc['was'].to_i
  when 0
    :off
  when 1
    :slow_only
  when 2
    :all
  else
    raise "Error: illegal profiling level value #{doc['was']}"
  end
end
profiling_level=(level) click to toggle source

Set this database's profiling level. If profiling is enabled, you can get the results using #profiling_info.

@param [Symbol] level acceptable options are :off, :slow_only, or :all.

# File lib/mongo/db.rb, line 585
def profiling_level=(level)
  oh = BSON::OrderedHash.new
  oh[:profile] = case level
                 when :off
                   0
                 when :slow_only
                   1
                 when :all
                   2
                 else
                   raise "Error: illegal profiling level value #{level}"
                 end
  doc = command(oh, :check_response => false)
  ok?(doc) || raise(MongoDBError, "Error with profile command: #{doc.inspect}")
end
read_preference() click to toggle source

The value of the read preference. This will be either :primary, :secondary, or an object representing the tags to be read from.

# File lib/mongo/db.rb, line 633
def read_preference
  @read_preference
end
remove_stored_function(function_name) click to toggle source

Removes stored Javascript function from the database. Returns false if the function does not exist

@param [String] function_name

@return [Boolean]

# File lib/mongo/db.rb, line 164
def remove_stored_function(function_name)
  if self[SYSTEM_JS_COLLECTION].find_one({"_id" => function_name})
    self[SYSTEM_JS_COLLECTION].remove({"_id" => function_name}, :safe => true)
  else
    return false
  end
end
remove_user(username) click to toggle source

Remove the given user from this database. Returns false if the user doesn't exist in the system.

@param [String] username

@return [Boolean]

# File lib/mongo/db.rb, line 196
def remove_user(username)
  if self[SYSTEM_USER_COLLECTION].find_one({:user => username})
    self[SYSTEM_USER_COLLECTION].remove({:user => username}, :safe => true)
  else
    return false
  end
end
rename_collection(from, to) click to toggle source

Rename a collection.

@param [String] from original collection name. @param [String] to new collection name.

@return [True] returns true on success.

@raise MongoDBError if there's an error renaming the collection.

# File lib/mongo/db.rb, line 424
def rename_collection(from, to)
  oh = BSON::OrderedHash.new
  oh[:renameCollection] = "#{@name}.#{from}"
  oh[:to] = "#{@name}.#{to}"
  doc = DB.new('admin', @connection).command(oh, :check_response => false)
  ok?(doc) || raise(MongoDBError, "Error renaming collection: #{doc.inspect}")
end
reset_error_history() click to toggle source

Reset the error history of this database

Calls to #previous_error will only return errors that have occurred since the most recent call to this method.

@return [Hash]

# File lib/mongo/db.rb, line 382
def reset_error_history
  command(:reseterror => 1)
end
stats() click to toggle source

Return stats on this database. Uses MongoDB's dbstats command.

@return [Hash]

# File lib/mongo/db.rb, line 468
def stats
  self.command({:dbstats => 1})
end
strict?() click to toggle source

Returns the value of the strict flag.

# File lib/mongo/db.rb, line 44
def strict?; @strict; end
validate_collection(name) click to toggle source

Validate a named collection.

@param [String] name the collection name.

@return [Hash] validation information.

@raise [MongoDBError] if the command fails or there's a problem with the validation

data, or if the collection is invalid.
# File lib/mongo/db.rb, line 616
def validate_collection(name)
  cmd = BSON::OrderedHash.new
  cmd[:validate] = name
  cmd[:full] = true
  doc = command(cmd, :check_response => false)
  if !ok?(doc)
    raise MongoDBError, "Error with validate command: #{doc.inspect}"
  end
  if (doc.has_key?('valid') && !doc['valid']) || (doc['result'] =~ /\b(exception|corrupt)\b/)
    raise MongoDBError, "Error: invalid collection #{name}: #{doc.inspect}"
  end
  doc
end

Private Instance Methods

system_command_collection() click to toggle source
# File lib/mongo/db.rb, line 639
def system_command_collection
  Collection.new(SYSTEM_COMMAND_COLLECTION, self)
end