Class Mongo::DB
In: lib/mongo/db.rb
Parent: Object

A MongoDB database.

Methods

Constants

SYSTEM_NAMESPACE_COLLECTION = "system.namespaces"
SYSTEM_INDEX_COLLECTION = "system.indexes"
SYSTEM_PROFILE_COLLECTION = "system.profile"
SYSTEM_USER_COLLECTION = "system.users"
SYSTEM_JS_COLLECTION = "system.js"
SYSTEM_COMMAND_COLLECTION = "$cmd"

Attributes

cache_time  [RW]  The length of time that 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

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

[Source]

# File lib/mongo/db.rb, line 79
    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

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

[Source]

# File lib/mongo/db.rb, line 148
    def add_stored_function(function_name, code)
      self[SYSTEM_JS_COLLECTION].save(
        {
          "_id" => function_name, 
          :value => BSON::Code.new(code)
        }
      )
    end

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

@return [Hash] an object representing the user.

[Source]

# File lib/mongo/db.rb, line 178
    def add_user(username, password)
      users = self[SYSTEM_USER_COLLECTION]
      user  = users.find_one({:user => username}) || {:user => username}
      user['pwd'] = Mongo::Support.hash_password(username, password)
      users.save(user)
      return user
    end

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

[Source]

# File lib/mongo/db.rb, line 109
    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
        @connection.authenticate_pools
      end

      issue_authentication(username, password, save_auth)
    end

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]

[Source]

# File lib/mongo/db.rb, line 306
    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

Get an array of collection names in this database.

@return [Array]

[Source]

# File lib/mongo/db.rb, line 228
    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

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

@return [Array<Mongo::Collection>]

[Source]

# File lib/mongo/db.rb, line 237
    def collections
      collection_names.map do |name|
        Collection.new(name, self)
      end
    end

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]

[Source]

# File lib/mongo/db.rb, line 250
    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

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

[Source]

# File lib/mongo/db.rb, line 496
    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 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]

[Source]

# File lib/mongo/db.rb, line 278
    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 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.

[Source]

# File lib/mongo/db.rb, line 388
    def dereference(dbref)
      collection(dbref.namespace).find_one("_id" => dbref.object_id)
    end

Drop a collection by name.

@param [String, Symbol] name

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

[Source]

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

      ok?(command(:drop => name))
    end

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

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

@return [True] returns true on success.

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

[Source]

# File lib/mongo/db.rb, line 436
    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

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

@return [Boolean]

[Source]

# File lib/mongo/db.rb, line 352
    def error?
      get_last_error['err'] != nil
    end

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.

[Source]

# File lib/mongo/db.rb, line 399
    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

A shortcut returning db plus dot plus collection name.

@param [String] collection_name

@return [String]

[Source]

# File lib/mongo/db.rb, line 531
    def full_collection_name(collection_name)
      "#{@name}.#{collection_name}"
    end

Run the getlasterror command with the specified replication options.

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

@return [Hash] the entire response to getlasterror.

@raise [MongoDBError] if the operation fails.

[Source]

# File lib/mongo/db.rb, line 339
    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

Get information on the indexes for the given collection. Normally called by 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.

[Source]

# File lib/mongo/db.rb, line 451
    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

[Source]

# File lib/mongo/db.rb, line 120
    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

[Source]

# File lib/mongo/db.rb, line 215
    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

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]

[Source]

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

      issue_logout(opts)
    end

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

@param [Hash] doc

@return [Boolean]

[Source]

# File lib/mongo/db.rb, line 472
    def ok?(doc)
      Mongo::Support.ok?(doc)
    end

The primary key factory object (or nil).

@return [Object, Nil]

[Source]

# File lib/mongo/db.rb, line 538
    def pk_factory
      @pk_factory
    end

Specify a primary key factory if not already set.

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

[Source]

# File lib/mongo/db.rb, line 545
    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

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

This command only returns errors that have occured since the last call to DB#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.

[Source]

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

Get the current profiling information.

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

[Source]

# File lib/mongo/db.rb, line 599
    def profiling_info
      Cursor.new(Collection.new(SYSTEM_PROFILE_COLLECTION, self), :selector => {}).to_a
    end

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

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

@core profiling profiling_level-instance_method

[Source]

# File lib/mongo/db.rb, line 559
    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

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

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

[Source]

# File lib/mongo/db.rb, line 580
    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

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

[Source]

# File lib/mongo/db.rb, line 628
    def read_preference
      @read_preference
    end

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

@param [String] function_name

@return [Boolean]

[Source]

# File lib/mongo/db.rb, line 163
    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 the given user from this database. Returns false if the user doesn‘t exist in the system.

@param [String] username

@return [Boolean]

[Source]

# File lib/mongo/db.rb, line 192
    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 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.

[Source]

# File lib/mongo/db.rb, line 419
    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 the error history of this database

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

@return [Hash]

[Source]

# File lib/mongo/db.rb, line 377
    def reset_error_history
      command(:reseterror => 1)
    end

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

@return [Hash]

[Source]

# File lib/mongo/db.rb, line 463
    def stats
      self.command({:dbstats => 1})
    end

Returns the value of the strict flag.

[Source]

# File lib/mongo/db.rb, line 46
    def strict?; @strict; end

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.

[Source]

# File lib/mongo/db.rb, line 611
    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/i)
        raise MongoDBError, "Error: invalid collection #{name}: #{doc.inspect}"
      end
      doc
    end

[Validate]