Class: Mongo::DB
- Inherits:
-
Object
- Object
- Mongo::DB
- Defined in:
- lib/mongo/db.rb
Overview
A Mongo 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"
Instance Attribute Summary collapse
-
#host ⇒ Object
readonly
Host to which we are currently connected.
-
#name ⇒ Object
readonly
The name of the database.
-
#nodes ⇒ Object
readonly
An array of [host, port] pairs.
-
#pk_factory ⇒ Object
A primary key factory object (or
nil
). -
#port ⇒ Object
readonly
Port to which we are currently connected.
-
#socket ⇒ Object
readonly
The database’s socket.
-
#strict ⇒ Object
writeonly
Strict mode enforces collection existence checks.
Instance Method Summary collapse
- #_synchronize(&block) ⇒ Object
- #admin ⇒ Object
-
#authenticate(username, password) ⇒ Object
Returns true if
username
haspassword
inSYSTEM_USER_COLLECTION
. - #auto_reconnect? ⇒ Boolean
-
#close ⇒ Object
Close the connection to the database.
-
#collection(name) ⇒ Object
(also: #[])
Return a collection.
-
#collection_names ⇒ Object
Returns an array of collection names in this database.
-
#collections ⇒ Object
Retruns an array of Collection instances, one for each collection in this database.
-
#collections_info(coll_name = nil) ⇒ Object
Returns a cursor over query result hashes.
- #connect_to_master ⇒ Object
- #connected? ⇒ Boolean
-
#count(collection_name, selector = {}) ⇒ Object
DEPRECATED - use Collection.find(selector).count() instead.
-
#create_collection(name, options = {}) ⇒ Object
Create a collection.
-
#create_index(collection_name, field_or_spec, unique = false) ⇒ Object
Create a new index on
collection_name
. -
#db_command(selector, use_admin_db = false) ⇒ Object
DB commands need to be ordered, so selector must be an OrderedHash (or a Hash with only one element).
-
#dereference(dbref) ⇒ Object
Dereference a DBRef, getting the document it points to.
-
#drop_collection(name) ⇒ Object
Drop collection
name
. -
#drop_index(collection_name, name) ⇒ Object
Drop index
name
fromcollection_name
. -
#error ⇒ Object
Returns the error message from the most recently executed database operation for this connection, or
nil
if there was no error. -
#error? ⇒ Boolean
Returns
true
if an error was caused by the most recently executed database operation. -
#eval(code, *args) ⇒ Object
Evaluate a JavaScript expression on MongoDB.
- #full_coll_name(collection_name) ⇒ Object
-
#index_information(collection_name) ⇒ Object
Get information on the indexes for the collection
collection_name
. -
#initialize(db_name, nodes, options = {}) ⇒ DB
constructor
Instances of DB are normally obtained by calling Mongo#db.
-
#insert_into_db(collection_name, objects) ⇒ Object
Insert
objects
intocollection_name
. -
#logout ⇒ Object
Deauthorizes use for this database for this connection.
-
#master ⇒ Object
Returns a string of the form “host:port” that points to the master database.
-
#master? ⇒ Boolean
Returns true if this database is a master (or is not paired with any other database), false if it is a slave.
-
#modify_in_db(collection_name, selector, obj) ⇒ Object
DEPRECATED - use Collection#update instead.
-
#ok?(doc) ⇒ Boolean
Return
true
ifdoc
contains an ‘ok’ field with the value 1. -
#previous_error ⇒ Object
Get the most recent error to have occured on this database.
-
#query(collection, query, admin = false) ⇒ Object
Returns a Cursor over the query results.
- #receive_full(length) ⇒ Object
-
#remove_from_db(collection_name, selector) ⇒ Object
Remove the records that match
selector
fromcollection_name
. -
#rename_collection(from, to) ⇒ Object
Rename collection
from
toto
. -
#replace_in_db(collection_name, selector, obj) ⇒ Object
Update records in
collection_name
that matchselector
by applyingobj
as an update. -
#repsert_in_db(collection_name, selector, obj) ⇒ Object
Update records in
collection_name
that matchselector
by applyingobj
as an update. -
#reset_error_history ⇒ Object
Reset the error history of this database.
-
#send_message(msg) ⇒ Object
Send a MsgMessage to the database.
-
#send_query_message(query_message) ⇒ Object
Used by a Cursor to lazily send the query to the database.
- #send_to_db(message) ⇒ Object
- #slave_ok? ⇒ Boolean
-
#strict? ⇒ Boolean
Returns the value of the
strict
flag.
Constructor Details
#initialize(db_name, nodes, options = {}) ⇒ DB
Instances of DB are normally obtained by calling Mongo#db.
- db_name
-
The database name
- nodes
-
An array of [host, port] pairs. See Connection#new, which offers a more flexible way of defining nodes.
- options
-
A hash of options.
Options:
- :strict
-
If true, collections must exist to be accessed and must not exist to be created. See #collection and #create_collection.
- :pk
-
A primary key factory object that must respond to :create_pk, 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; this means that the object is being used in a repsert but it already exists.) The idea here is that when ever a record is inserted, the :pk object’s
create_pk
method will be called and the new hash returned will be inserted. - :slave_ok
-
Only used if
nodes
contains only one host/port. If false, when connecting to that host/port we check to see if the server is the master. If it is not, an error is thrown. - :auto_reconnect
-
If the connection gets closed (for example, we have a server pair and saw the “not master” error, which closes the connection), then automatically try to reconnect to the master or to the single server we have been given. Defaults to
false
.
When a DB object first connects to a pair, it will find the master instance and connect to that one. On socket error or if we recieve a “not master” error, we again find the master of the pair.
114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/mongo/db.rb', line 114 def initialize(db_name, nodes, ={}) case db_name when Symbol, String else raise TypeError, "db_name must be a string or symbol" end [" ", ".", "$", "/", "\\"].each do |invalid_char| if db_name.include? invalid_char raise InvalidName, "database names cannot contain the character '#{invalid_char}'" end end if db_name.empty? raise InvalidName, "database name cannot be the empty string" end @name, @nodes = db_name, nodes @strict = [:strict] @pk_factory = [:pk] @slave_ok = [:slave_ok] && @nodes.length == 1 # only OK if one node @auto_reconnect = [:auto_reconnect] @semaphore = Object.new @semaphore.extend Mutex_m @socket = nil connect_to_master end |
Instance Attribute Details
#host ⇒ Object (readonly)
Host to which we are currently connected.
52 53 54 |
# File 'lib/mongo/db.rb', line 52 def host @host end |
#name ⇒ Object (readonly)
The name of the database.
49 50 51 |
# File 'lib/mongo/db.rb', line 49 def name @name end |
#nodes ⇒ Object (readonly)
An array of [host, port] pairs.
57 58 59 |
# File 'lib/mongo/db.rb', line 57 def nodes @nodes end |
#pk_factory ⇒ Object
A primary key factory object (or nil
). See the README.doc file or DB#new for details.
67 68 69 |
# File 'lib/mongo/db.rb', line 67 def pk_factory @pk_factory end |
#port ⇒ Object (readonly)
Port to which we are currently connected.
54 55 56 |
# File 'lib/mongo/db.rb', line 54 def port @port end |
#socket ⇒ Object (readonly)
The database’s socket. For internal (and Cursor) use only.
60 61 62 |
# File 'lib/mongo/db.rb', line 60 def socket @socket 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 off (false
) by default. Its value can be changed at any time.
43 44 45 |
# File 'lib/mongo/db.rb', line 43 def strict=(value) @strict = value end |
Instance Method Details
#_synchronize(&block) ⇒ Object
550 551 552 |
# File 'lib/mongo/db.rb', line 550 def _synchronize &block @semaphore.synchronize &block end |
#authenticate(username, password) ⇒ Object
Returns true if username
has password
in SYSTEM_USER_COLLECTION
. name
is username, password
is plaintext password.
169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/mongo/db.rb', line 169 def authenticate(username, password) doc = db_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)}") ok?(db_command(auth)) end |
#auto_reconnect? ⇒ Boolean
63 |
# File 'lib/mongo/db.rb', line 63 def auto_reconnect?; @auto_reconnect; end |
#close ⇒ Object
Close the connection to the database.
331 332 333 334 335 336 337 |
# File 'lib/mongo/db.rb', line 331 def close if @socket s = @socket @socket = nil s.close end end |
#collection(name) ⇒ Object Also known as: []
Return a collection. If strict
is false, will return existing or new collection. If strict
is true, will raise an error if collection name
does not already exists.
251 252 253 254 |
# File 'lib/mongo/db.rb', line 251 def collection(name) return Collection.new(self, name) if !strict? || collection_names.include?(name) raise "Collection #{name} doesn't exist. Currently in strict mode." end |
#collection_names ⇒ Object
Returns an array of collection names in this database.
189 190 191 192 193 |
# File 'lib/mongo/db.rb', line 189 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 ⇒ Object
Retruns an array of Collection instances, one for each collection in this database.
197 198 199 200 201 |
# File 'lib/mongo/db.rb', line 197 def collections collection_names.map do |collection_name| Collection.new(self, collection_name) end end |
#collections_info(coll_name = nil) ⇒ Object
Returns a cursor over query result hashes. Each hash contains a ‘name’ string and optionally an ‘options’ hash. If coll_name
is specified, an array of length 1 is returned.
206 207 208 209 210 |
# File 'lib/mongo/db.rb', line 206 def collections_info(coll_name=nil) selector = {} selector[:name] = full_coll_name(coll_name) if coll_name query(Collection.new(self, SYSTEM_NAMESPACE_COLLECTION), Query.new(selector)) end |
#connect_to_master ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'lib/mongo/db.rb', line 141 def connect_to_master close if @socket @host = @port = nil @nodes.detect { |hp| @host, @port = *hp begin @socket = TCPSocket.new(@host, @port) @socket.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_NODELAY, 1) # Check for master. Can't call master? because it uses mutex, # which may already be in use during this call. semaphore_is_locked = @semaphore.locked? @semaphore.unlock if semaphore_is_locked is_master = master? @semaphore.lock if semaphore_is_locked @slave_ok || is_master rescue SocketError, SystemCallError, IOError => ex close if @socket false end } raise "error: failed to connect to any given host:port" unless @socket end |
#connected? ⇒ Boolean
339 340 341 |
# File 'lib/mongo/db.rb', line 339 def connected? @socket != nil end |
#count(collection_name, selector = {}) ⇒ Object
DEPRECATED - use Collection.find(selector).count() instead
406 407 408 409 |
# File 'lib/mongo/db.rb', line 406 def count(collection_name, selector={}) warn "DB#count is deprecated and will be removed. Please use Collection.find(selector).count instead." collection(collection_name).find(selector).count() end |
#create_collection(name, options = {}) ⇒ Object
Create a collection. If strict
is false, will return existing or new collection. If strict
is true, will raise an error if collection name
already exists.
Options is an optional hash:
- :capped
-
Boolean. If not specified, capped is
false
. - :size
-
If
capped
istrue
, specifies the maximum number of bytes. Iffalse
, specifies the initial extent of the collection. - :max
-
Max number of records in a capped collection. Optional.
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/mongo/db.rb', line 225 def create_collection(name, ={}) # First check existence if collection_names.include?(name) if strict? raise "Collection #{name} already exists. Currently in strict mode." else return Collection.new(self, name) end end # Create new collection oh = OrderedHash.new oh[:create] = name doc = db_command(oh.merge( || {})) ok = doc['ok'] return Collection.new(self, name) if ok.kind_of?(Numeric) && (ok.to_i == 1 || ok.to_i == 0) raise "Error creating collection: #{doc.inspect}" end |
#create_index(collection_name, field_or_spec, unique = false) ⇒ Object
Create a new index on collection_name
. field_or_spec
should be either a single field name or a Array of [field name, direction] pairs. Directions should be specified as Mongo::ASCENDING or Mongo::DESCENDING. Normally called by Collection#create_index. If unique
is true the index will enforce a uniqueness constraint.
473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 |
# File 'lib/mongo/db.rb', line 473 def create_index(collection_name, field_or_spec, unique=false) field_h = OrderedHash.new if field_or_spec.is_a?(String) || field_or_spec.is_a?(Symbol) field_h[field_or_spec.to_s] = 1 else field_or_spec.each { |f| field_h[f[0].to_s] = f[1] } end name = gen_index_name(field_h) sel = { :name => name, :ns => full_coll_name(collection_name), :key => field_h, :unique => unique } _synchronize { send_to_db(InsertMessage.new(@name, SYSTEM_INDEX_COLLECTION, false, sel)) } name end |
#db_command(selector, use_admin_db = false) ⇒ Object
DB commands need to be ordered, so selector must be an OrderedHash (or a Hash with only one element). What DB commands really need is that the “command” key be first.
Do not call this. Intended for driver use only.
538 539 540 541 542 543 544 545 546 547 548 |
# File 'lib/mongo/db.rb', line 538 def db_command(selector, use_admin_db=false) if !selector.kind_of?(OrderedHash) if !selector.kind_of?(Hash) || selector.keys.length > 1 raise "db_command must be given an OrderedHash when there is more than one key" end end q = Query.new(selector) q.number_to_return = 1 query(Collection.new(self, SYSTEM_COMMAND_COLLECTION), q, use_admin_db).next_object end |
#dereference(dbref) ⇒ Object
Dereference a DBRef, getting the document it points to.
412 413 414 |
# File 'lib/mongo/db.rb', line 412 def dereference(dbref) collection(dbref.namespace).find_one("_id" => dbref.object_id) end |
#drop_collection(name) ⇒ Object
Drop collection name
. Returns true
on success or if the collection does not exist, false
otherwise.
259 260 261 262 263 |
# File 'lib/mongo/db.rb', line 259 def drop_collection(name) return true unless collection_names.include?(name) ok?(db_command(:drop => name)) end |
#drop_index(collection_name, name) ⇒ Object
Drop index name
from collection_name
. Normally called from Collection#drop_index or Collection#drop_indexes.
445 446 447 448 449 450 451 |
# File 'lib/mongo/db.rb', line 445 def drop_index(collection_name, name) oh = OrderedHash.new oh[:deleteIndexes] = collection_name oh[:index] = name doc = db_command(oh) raise "Error with drop_index command: #{doc.inspect}" unless ok?(doc) end |
#error ⇒ Object
Returns the error message from the most recently executed database operation for this connection, or nil
if there was no error.
Note: as of this writing, errors are only detected on the db server for certain kinds of operations (writes). The plan is to change this so that all operations will set the error if needed.
271 272 273 274 275 |
# File 'lib/mongo/db.rb', line 271 def error doc = db_command(:getlasterror => 1) raise "error retrieving last error: #{doc}" unless ok?(doc) doc['err'] end |
#error? ⇒ Boolean
Returns true
if an error was caused by the most recently executed database operation.
Note: as of this writing, errors are only detected on the db server for certain kinds of operations (writes). The plan is to change this so that all operations will set the error if needed.
283 284 285 |
# File 'lib/mongo/db.rb', line 283 def error? error != nil end |
#eval(code, *args) ⇒ Object
Evaluate a JavaScript expression on MongoDB. code
should be a string or Code instance containing a JavaScript expression. Additional arguments will be passed to that expression when it is run on the server.
420 421 422 423 424 425 426 427 428 429 430 431 |
# File 'lib/mongo/db.rb', line 420 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 = db_command(oh) return doc['retval'] if ok?(doc) raise OperationFailure, "eval failed: #{doc['errmsg']}" end |
#full_coll_name(collection_name) ⇒ Object
523 524 525 |
# File 'lib/mongo/db.rb', line 523 def full_coll_name(collection_name) "#{@name}.#{collection_name}" end |
#index_information(collection_name) ⇒ Object
Get information on the indexes for the collection collection_name
. Normally called by Collection#index_information. Returns a hash where the keys are index names (as returned by Collection#create_index and the values are lists of [key, direction] pairs specifying the index (as passed to Collection#create_index).
458 459 460 461 462 463 464 465 |
# File 'lib/mongo/db.rb', line 458 def index_information(collection_name) sel = {:ns => full_coll_name(collection_name)} info = {} query(Collection.new(self, SYSTEM_INDEX_COLLECTION), Query.new(sel)).each { |index| info[index['name']] = index['key'].to_a } info end |
#insert_into_db(collection_name, objects) ⇒ Object
Insert objects
into collection_name
. Normally called by Collection#insert. Returns a new array containing the _ids of the inserted documents.
496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 |
# File 'lib/mongo/db.rb', line 496 def insert_into_db(collection_name, objects) _synchronize { if @pk_factory objects.collect! { |o| @pk_factory.create_pk(o) } else objects = objects.collect do |o| o[:_id] || o['_id'] ? o : o.merge!(:_id => ObjectID.new) end end send_to_db(InsertMessage.new(@name, collection_name, true, *objects)) objects.collect { |o| o[:_id] || o['_id'] } } end |
#logout ⇒ Object
Deauthorizes use for this database for this connection.
183 184 185 186 |
# File 'lib/mongo/db.rb', line 183 def logout doc = db_command(:logout => 1) raise "error logging out: #{doc.inspect}" unless ok?(doc) end |
#master ⇒ Object
Returns a string of the form “host:port” that points to the master database. Works even if this is the master database.
318 319 320 321 322 323 324 325 326 327 328 |
# File 'lib/mongo/db.rb', line 318 def master doc = db_command(:ismaster => 1) is_master = doc['ismaster'] raise "Error retrieving master database: #{doc.inspect}" unless ok?(doc) && is_master.kind_of?(Numeric) case is_master.to_i when 1 "#@host:#@port" else doc['remote'] end end |
#master? ⇒ Boolean
Returns true if this database is a master (or is not paired with any other database), false if it is a slave.
310 311 312 313 314 |
# File 'lib/mongo/db.rb', line 310 def master? doc = db_command(:ismaster => 1) is_master = doc['ismaster'] ok?(doc) && is_master.kind_of?(Numeric) && is_master.to_i == 1 end |
#modify_in_db(collection_name, selector, obj) ⇒ Object
DEPRECATED - use Collection#update instead
389 390 391 392 |
# File 'lib/mongo/db.rb', line 389 def modify_in_db(collection_name, selector, obj) warn "DB#modify_in_db is deprecated and will be removed. Please use Collection#update instead." replace_in_db(collection_name, selector, obj) end |
#ok?(doc) ⇒ Boolean
Return true
if doc
contains an ‘ok’ field with the value 1.
528 529 530 531 |
# File 'lib/mongo/db.rb', line 528 def ok?(doc) ok = doc['ok'] ok.kind_of?(Numeric) && ok.to_i == 1 end |
#previous_error ⇒ Object
Get the most recent error to have occured on this database
Only returns errors that have occured since the last call to DB#reset_error_history - returns nil
if there is no such error.
291 292 293 294 295 296 297 298 |
# File 'lib/mongo/db.rb', line 291 def previous_error error = db_command(:getpreverror => 1) if error["err"] error else nil end end |
#query(collection, query, admin = false) ⇒ Object
Returns a Cursor over the query results.
Note that the query gets sent lazily; the cursor calls #send_query_message when needed. If the caller never requests an object from the cursor, the query never gets sent.
363 364 365 |
# File 'lib/mongo/db.rb', line 363 def query(collection, query, admin=false) Cursor.new(self, collection, query, admin) end |
#receive_full(length) ⇒ Object
343 344 345 346 347 348 349 350 351 |
# File 'lib/mongo/db.rb', line 343 def receive_full(length) = "" while .length < length do chunk = @socket.recv(length - .length) raise "connection closed" unless chunk.length > 0 += chunk end end |
#remove_from_db(collection_name, selector) ⇒ Object
Remove the records that match selector
from collection_name
. Normally called by Collection#remove or Collection#clear.
374 375 376 377 378 |
# File 'lib/mongo/db.rb', line 374 def remove_from_db(collection_name, selector) _synchronize { send_to_db(RemoveMessage.new(@name, collection_name, selector)) } end |
#rename_collection(from, to) ⇒ Object
Rename collection from
to to
. Meant to be called by Collection#rename.
435 436 437 438 439 440 441 |
# File 'lib/mongo/db.rb', line 435 def rename_collection(from, to) oh = OrderedHash.new oh[:renameCollection] = "#{@name}.#{from}" oh[:to] = "#{@name}.#{to}" doc = db_command(oh, true) raise "Error renaming collection: #{doc.inspect}" unless ok?(doc) end |
#replace_in_db(collection_name, selector, obj) ⇒ Object
Update records in collection_name
that match selector
by applying obj
as an update. Normally called by Collection#replace.
382 383 384 385 386 |
# File 'lib/mongo/db.rb', line 382 def replace_in_db(collection_name, selector, obj) _synchronize { send_to_db(UpdateMessage.new(@name, collection_name, selector, obj, false)) } end |
#repsert_in_db(collection_name, selector, obj) ⇒ Object
Update records in collection_name
that match selector
by applying obj
as an update. If no match, inserts (???). Normally called by Collection#repsert.
397 398 399 400 401 402 403 |
# File 'lib/mongo/db.rb', line 397 def repsert_in_db(collection_name, selector, obj) _synchronize { obj = @pk_factory.create_pk(obj) if @pk_factory send_to_db(UpdateMessage.new(@name, collection_name, selector, obj, true)) obj } end |
#reset_error_history ⇒ Object
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.
304 305 306 |
# File 'lib/mongo/db.rb', line 304 def reset_error_history db_command(:reseterror => 1) end |
#send_message(msg) ⇒ Object
Send a MsgMessage to the database.
354 355 356 |
# File 'lib/mongo/db.rb', line 354 def (msg) send_to_db(MsgMessage.new(msg)) end |
#send_query_message(query_message) ⇒ Object
Used by a Cursor to lazily send the query to the database.
368 369 370 |
# File 'lib/mongo/db.rb', line 368 def () send_to_db() end |
#send_to_db(message) ⇒ Object
512 513 514 515 516 517 518 519 520 521 |
# File 'lib/mongo/db.rb', line 512 def send_to_db() connect_to_master if !connected? && @auto_reconnect begin @socket.print(.buf.to_s) @socket.flush rescue => ex close raise ex end end |
#slave_ok? ⇒ Boolean
62 |
# File 'lib/mongo/db.rb', line 62 def slave_ok?; @slave_ok; end |
#strict? ⇒ Boolean
Returns the value of the strict
flag.
46 |
# File 'lib/mongo/db.rb', line 46 def strict?; @strict; end |