Class: Mongo::DB

Inherits:
Object show all
Defined in:
lib/mongo/db.rb

Overview

A MongoDB database.

Constant Summary collapse

SYSTEM_NAMESPACE_COLLECTION =
"system.namespaces"
SYSTEM_INDEX_COLLECTION =
"system.indexes"
SYSTEM_PROFILE_COLLECTION =
"system.profile"
SYSTEM_USER_COLLECTION =
"system.users"
SYSTEM_COMMAND_COLLECTION =
"$cmd"
@@current_request_id =

Counter for generating unique request ids.

0

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(db_name, connection, options = {}) ⇒ DB

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

Parameters:

  • db_name (String)

    the database name.

  • connection (Mongo::Connection)

    a connection object pointing to MongoDB. Note that databases are usually instantiated via the Connection class. See the examples below.

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • strict (Boolean) — default: False

    If true, collections must exist to be accessed and must not exist to be created. See DB#collection and DB#create_collection.

  • pk (Object, #create_pk(doc)) — default: Mongo::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).



67
68
69
70
71
72
# File 'lib/mongo/db.rb', line 67

def initialize(db_name, connection, options={})
  @name       = validate_db_name(db_name)
  @connection = connection
  @strict     = options[:strict]
  @pk_factory = options[:pk]
end

Instance Attribute Details

#connectionObject (readonly)

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



50
51
52
# File 'lib/mongo/db.rb', line 50

def connection
  @connection
end

#nameObject (readonly)

The name of the database.



47
48
49
# File 'lib/mongo/db.rb', line 47

def name
  @name
end

#strict=(value) ⇒ Object (writeonly)

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.



41
42
43
# File 'lib/mongo/db.rb', line 41

def strict=(value)
  @strict = value
end

Instance Method Details

#add_user(username, password) ⇒ Hash

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

Parameters:

  • username (String)
  • password (String)

Returns:

  • (Hash)

    an object representing the user.



112
113
114
115
116
117
118
# File 'lib/mongo/db.rb', line 112

def add_user(username, password)
  users = self[SYSTEM_USER_COLLECTION]
  user  = users.find_one({:user => username}) || {:user => username}
  user['pwd'] = hash_password(username, password)
  users.save(user)
  return user
end

#authenticate(username, password, save_authorization = true) ⇒ Boolean

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

Parameters:

  • username (String)
  • password (String)

Returns:

  • (Boolean)

Raises:



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/mongo/db.rb', line 85

def authenticate(username, password, save_authorization=true)
  doc = command(:getnonce => 1)
  raise "error retrieving nonce: #{doc}" unless ok?(doc)
  nonce = doc['nonce']

  auth = OrderedHash.new
  auth['authenticate'] = 1
  auth['user'] = username
  auth['nonce'] = nonce
  auth['key'] = Digest::MD5.hexdigest("#{nonce}#{username}#{hash_password(username, password)}")
  if ok?(command(auth))
    if save_authorization
      @connection.add_auth(@name, username, password)
    end
    true
  else
    raise(Mongo::AuthenticationError, "Failed to authenticate user '#{username}' on db '#{self.name}'")
  end
end

#collection(name) ⇒ Mongo::Collection Also known as: []

Get a collection by name.

Parameters:

  • name (String)

    the collection name.

Returns:

Raises:

  • (MongoDBError)

    if collection does not already exist and we’re in strict mode.



228
229
230
231
# File 'lib/mongo/db.rb', line 228

def collection(name)
  return Collection.new(self, name, @pk_factory) if !strict? || collection_names.include?(name)
  raise MongoDBError, "Collection #{name} doesn't exist. Currently in strict mode."
end

#collection_namesArray

Get an array of collection names in this database.

Returns:

  • (Array)


154
155
156
157
158
# File 'lib/mongo/db.rb', line 154

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

#collectionsArray<Mongo::Collection>

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

Returns:



163
164
165
166
167
# File 'lib/mongo/db.rb', line 163

def collections
  collection_names.map do |collection_name|
    Collection.new(self, collection_name)
  end
end

#collections_info(coll_name = nil) ⇒ Mongo::Cursor

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.

Parameters:

  • coll_name (String) (defaults to: nil)

    return info for the specifed collection only.

Returns:



176
177
178
179
180
# File 'lib/mongo/db.rb', line 176

def collections_info(coll_name=nil)
  selector = {}
  selector[:name] = full_collection_name(coll_name) if coll_name
  Cursor.new(Collection.new(self, SYSTEM_NAMESPACE_COLLECTION), :selector => selector)
end

#command(selector, admin = false, check_response = false, sock = nil) ⇒ Hash

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.

It may be of interest hat a command in MongoDB is technically a kind of query that occurs on the system command collection ($cmd).

key, specifying the command to be performed.

collection.

command fails.

Parameters:

  • selector (OrderedHash, Hash)

    an OrderedHash, or a standard Hash with just one

  • admin (Boolean) (defaults to: false)

    If true, the command will be executed on the admin

  • check_response (Boolean) (defaults to: false)

    If true, will raise an exception if the

  • sock (Socket) (defaults to: nil)

    a socket to use. This is mainly for internal use.

Returns:

  • (Hash)

Raises:



433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
# File 'lib/mongo/db.rb', line 433

def command(selector, admin=false, check_response=false, sock=nil)
  raise MongoArgumentError, "command must be given a selector" unless selector.is_a?(Hash) && !selector.empty?
  if selector.class.eql?(Hash) && selector.keys.length > 1
    raise MongoArgumentError, "DB#command requires an OrderedHash when hash contains multiple keys"
  end

  result = Cursor.new(system_command_collection, :admin => admin,
    :limit => -1, :selector => selector, :socket => sock).next_document

  if check_response && !ok?(result)
    raise OperationFailure, "Database command '#{selector.keys.first}' failed."
  else
    result
  end
end

#create_collection(name, options = {}) ⇒ Mongo::Collection

Create a collection.

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

Parameters:

  • name (String)

    the name of the new collection.

  • options (Hash) (defaults to: {})

    a customizable set of options

Options Hash (options):

  • :capped (Boolean) — default: False

    created a capped collection.

  • :size (Integer) — default: 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.

  • :max (Integer) — default: Nil

    If capped is true, indicates the maximum number of records in a capped collection.

Returns:

Raises:

  • (MongoDBError)

    raised under two conditions: either we’re in strict mode and the collection already exists or collection creation fails on the server.



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'lib/mongo/db.rb', line 202

def create_collection(name, options={})
  # Does the collection already exist?
  if collection_names.include?(name)
    if strict?
      raise MongoDBError, "Collection #{name} already exists. Currently in strict mode."
    else
      return Collection.new(self, name)
    end
  end

  # Create a new collection.
  oh = OrderedHash.new
  oh[:create] = name
  doc = command(oh.merge(options || {}))
  ok = doc['ok']
  return Collection.new(self, name, @pk_factory) if ok.kind_of?(Numeric) && (ok.to_i == 1 || ok.to_i == 0)
  raise MongoDBError, "Error creating collection: #{doc.inspect}"
end

#create_index(collection_name, field_or_spec, unique = false) ⇒ String

Create a new index on the given collection. Normally called by Collection#create_index.

Parameters:

  • collection_name (String)
  • field_or_spec (String, Array)

    either either a single field name or an array of [field name, direction] pairs. Directions should be specified as Mongo::ASCENDING or Mongo::DESCENDING.

  • unique (Boolean) (defaults to: false)

    if true, the created index will enforce a uniqueness constraint.

Returns:

  • (String)

    the name of the index created.



397
398
399
# File 'lib/mongo/db.rb', line 397

def create_index(collection_name, field_or_spec, unique=false)
  self.collection(collection_name).create_index(field_or_spec, unique)
end

#dereference(dbref) ⇒ Hash

Dereference a DBRef, returning the document it points to.

Parameters:

Returns:

  • (Hash)

    the document indicated by the db reference.

See Also:



314
315
316
# File 'lib/mongo/db.rb', line 314

def dereference(dbref)
  collection(dbref.namespace).find_one("_id" => dbref.object_id)
end

#drop_collection(name) ⇒ Boolean

Drop a collection by name.

Parameters:

  • name (String)

Returns:

  • (Boolean)

    True on success or if the collection names doesn’t exist.



239
240
241
242
243
# File 'lib/mongo/db.rb', line 239

def drop_collection(name)
  return true unless collection_names.include?(name)

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

#drop_index(collection_name, index_name) ⇒ True

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

Parameters:

  • collection_name (String)
  • index_name (String)

Returns:

  • (True)

    returns true on success.

Raises:

  • MongoDBError if there’s an error renaming the collection.



363
364
365
366
367
368
369
# File 'lib/mongo/db.rb', line 363

def drop_index(collection_name, index_name)
  oh = OrderedHash.new
  oh[:deleteIndexes] = collection_name
  oh[:index] = index_name
  doc = command(oh)
  ok?(doc) || raise(MongoDBError, "Error with drop_index command: #{doc.inspect}")
end

#errorString, Nil

Get the error message from the most recently executed database operation for this connection.

Returns:

  • (String, Nil)

    either the text describing the error or nil if no error has occurred.

Raises:



250
251
252
253
254
# File 'lib/mongo/db.rb', line 250

def error
  doc = command(:getlasterror => 1)
  raise MongoDBError, "error retrieving last error: #{doc}" unless ok?(doc)
  doc['err']
end

#error?Boolean

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

Returns:

  • (Boolean)


267
268
269
# File 'lib/mongo/db.rb', line 267

def error?
  error != nil
end

#eval(code, *args) ⇒ String

Evaluate a JavaScript expression in MongoDB.

Parameters:

  • code (String, Code)

    a JavaScript expression to evaluate server-side.

  • args (Integer, Hash)

    any additional argument to be passed to the code expression when it’s run on the server.

Returns:

  • (String)

    the return value of the function.

Raises:



325
326
327
328
329
330
331
332
333
334
335
336
# File 'lib/mongo/db.rb', line 325

def eval(code, *args)
  if not code.is_a? Code
    code = Code.new(code)
  end

  oh = OrderedHash.new
  oh[:$eval] = code
  oh[:args] = args
  doc = command(oh)
  return doc['retval'] if ok?(doc)
  raise OperationFailure, "eval failed: #{doc['errmsg']}"
end

#full_collection_name(collection_name) ⇒ String

A shortcut returning db plus dot plus collection name.

Parameters:

  • collection_name (String)

Returns:

  • (String)


454
455
456
# File 'lib/mongo/db.rb', line 454

def full_collection_name(collection_name)
  "#{@name}.#{collection_name}"
end

#index_information(collection_name) ⇒ Hash

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

Parameters:

  • collection_name (String)

Returns:

  • (Hash)

    keys are index names and the values are lists of [key, direction] pairs defining the index.



378
379
380
381
382
383
384
385
# File 'lib/mongo/db.rb', line 378

def index_information(collection_name)
  sel = {:ns => full_collection_name(collection_name)}
  info = {}
  Cursor.new(Collection.new(self, SYSTEM_INDEX_COLLECTION), :selector => sel).each { |index|
    info[index['name']] = index['key'].map {|k| k}
  }
  info
end

#last_statusHash

Get status information from the last operation on this connection.

Returns:

  • (Hash)

    a hash representing the status of the last db op.



259
260
261
# File 'lib/mongo/db.rb', line 259

def last_status
  command(:getlasterror => 1)
end

#logoutBoolean

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

Returns:

  • (Boolean)

Raises:



141
142
143
144
145
146
147
148
149
# File 'lib/mongo/db.rb', line 141

def logout
  doc = command(:logout => 1)
  if ok?(doc)
    @connection.remove_auth(@name)
    true
  else
    raise MongoDBError, "error logging out: #{doc.inspect}"
  end
end

#ok?(doc) ⇒ Boolean

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

Parameters:

  • doc (Hash)

Returns:

  • (Boolean)


406
407
408
409
# File 'lib/mongo/db.rb', line 406

def ok?(doc)
  ok = doc['ok']
  ok.kind_of?(Numeric) && ok.to_i == 1
end

#pk_factoryObject, Nil

The primary key factory object (or nil).

Returns:



461
462
463
# File 'lib/mongo/db.rb', line 461

def pk_factory
  @pk_factory
end

#pk_factory=(pk_factory) ⇒ Object

Specify a primary key factory if not already set.

Raises:



468
469
470
471
472
473
474
# File 'lib/mongo/db.rb', line 468

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_errorString, Nil

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.

Returns:

  • (String, Nil)

    the text of the error or nil if no error has occurred.



277
278
279
280
281
282
283
284
# File 'lib/mongo/db.rb', line 277

def previous_error
  error = command(:getpreverror => 1)
  if error["err"]
    error
  else
    nil
  end
end

#profiling_infoArray

Get the current profiling information.

Returns:

  • (Array)

    a list of documents containing profiling information.



522
523
524
# File 'lib/mongo/db.rb', line 522

def profiling_info
  Cursor.new(Collection.new(self, DB::SYSTEM_PROFILE_COLLECTION), :selector => {}).to_a
end

#profiling_levelSymbol

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

Returns:

  • (Symbol)

    :off, :slow_only, or :all



482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
# File 'lib/mongo/db.rb', line 482

def profiling_level
  oh = OrderedHash.new
  oh[:profile] = -1
  doc = command(oh)
  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) ⇒ Object

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

Parameters:

  • level (Symbol)

    acceptable options are :off, :slow_only, or :all.



503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
# File 'lib/mongo/db.rb', line 503

def profiling_level=(level)
  oh = 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)
  ok?(doc) || raise(MongoDBError, "Error with profile command: #{doc.inspect}")
end

#query(collection, query, admin = false) ⇒ Object

Deprecated.

please use Collection#find to create queries.

Returns a Cursor over the query results.

Note that the query gets sent lazily; the cursor calls Connection#send_message when needed. If the caller never requests an object from the cursor, the query never gets sent.



303
304
305
# File 'lib/mongo/db.rb', line 303

def query(collection, query, admin=false)
  Cursor.new(self, collection, query, admin)
end

#remove_user(username) ⇒ Boolean

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

Parameters:

  • username (String)

Returns:

  • (Boolean)


126
127
128
129
130
131
132
# File 'lib/mongo/db.rb', line 126

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) ⇒ True

Rename a collection.

Parameters:

  • from (String)

    original collection name.

  • to (String)

    new collection name.

Returns:

  • (True)

    returns true on success.

Raises:

  • MongoDBError if there’s an error renaming the collection.



346
347
348
349
350
351
352
# File 'lib/mongo/db.rb', line 346

def rename_collection(from, to)
  oh = OrderedHash.new
  oh[:renameCollection] = "#{@name}.#{from}"
  oh[:to] = "#{@name}.#{to}"
  doc = command(oh, true)
  ok?(doc) || raise(MongoDBError, "Error renaming collection: #{doc.inspect}")
end

#reset_error_historyHash

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.

Returns:

  • (Hash)


292
293
294
# File 'lib/mongo/db.rb', line 292

def reset_error_history
  command(:reseterror => 1)
end

#strict?Boolean

Returns the value of the strict flag.

Returns:

  • (Boolean)


44
# File 'lib/mongo/db.rb', line 44

def strict?; @strict; end

#validate_collection(name) ⇒ Hash

Validate a named collection.

Parameters:

  • name (String)

    the collection name.

Returns:

  • (Hash)

    validation information.

Raises:

  • (MongoDBError)

    if the command fails or there’s a problem with the validation data, or if the collection is invalid.



534
535
536
537
538
539
540
541
# File 'lib/mongo/db.rb', line 534

def validate_collection(name)
  doc = command(:validate => name)
  raise MongoDBError, "Error with validate command: #{doc.inspect}" unless ok?(doc)
  result = doc['result']
  raise MongoDBError, "Error with validation data: #{doc.inspect}" unless result.kind_of?(String)
  raise MongoDBError, "Error: invalid collection #{name}: #{doc.inspect}" if result =~ /\b(exception|corrupt)\b/i
  doc
end