mongo 0.18.2 → 0.18.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. data/README.rdoc +37 -28
  2. data/Rakefile +19 -0
  3. data/bin/objectid_benchmark.rb +23 -0
  4. data/examples/admin.rb +7 -6
  5. data/examples/capped.rb +3 -4
  6. data/examples/cursor.rb +4 -3
  7. data/examples/gridfs.rb +3 -2
  8. data/examples/index_test.rb +10 -9
  9. data/examples/info.rb +3 -2
  10. data/examples/queries.rb +3 -2
  11. data/examples/simple.rb +3 -2
  12. data/examples/strict.rb +2 -1
  13. data/examples/types.rb +4 -3
  14. data/lib/mongo.rb +29 -12
  15. data/lib/mongo/admin.rb +17 -2
  16. data/lib/mongo/collection.rb +230 -169
  17. data/lib/mongo/connection.rb +136 -91
  18. data/lib/mongo/cursor.rb +68 -40
  19. data/lib/mongo/db.rb +247 -123
  20. data/lib/mongo/{errors.rb → exceptions.rb} +6 -5
  21. data/lib/mongo/gridfs.rb +6 -0
  22. data/lib/mongo/gridfs/grid_store.rb +142 -94
  23. data/lib/mongo/types/binary.rb +11 -1
  24. data/lib/mongo/types/code.rb +6 -1
  25. data/lib/mongo/types/dbref.rb +7 -2
  26. data/lib/mongo/types/min_max_keys.rb +58 -0
  27. data/lib/mongo/types/objectid.rb +76 -20
  28. data/lib/mongo/types/regexp_of_holding.rb +5 -0
  29. data/lib/mongo/util/bson_ruby.rb +36 -2
  30. data/lib/mongo/util/byte_buffer.rb +18 -2
  31. data/lib/mongo/util/conversions.rb +6 -5
  32. data/lib/mongo/util/ordered_hash.rb +3 -1
  33. data/lib/mongo/util/support.rb +3 -0
  34. data/lib/mongo/util/xml_to_ruby.rb +7 -0
  35. data/test/test_bson.rb +48 -0
  36. data/test/test_collection.rb +13 -0
  37. data/test/test_connection.rb +35 -0
  38. data/test/test_conversions.rb +1 -1
  39. data/test/test_cursor.rb +37 -5
  40. data/test/test_db.rb +51 -2
  41. data/test/test_db_api.rb +4 -7
  42. data/test/test_grid_store.rb +10 -0
  43. data/test/test_objectid.rb +16 -2
  44. data/test/test_ordered_hash.rb +14 -0
  45. data/test/threading/test_threading_large_pool.rb +4 -4
  46. data/test/unit/db_test.rb +43 -0
  47. metadata +5 -7
  48. data/examples/benchmarks.rb +0 -42
  49. data/examples/blog.rb +0 -76
  50. data/lib/mongo/constants.rb +0 -15
  51. data/test/mongo-qa/_common.rb +0 -8
@@ -21,7 +21,7 @@ require 'thread'
21
21
 
22
22
  module Mongo
23
23
 
24
- # A Mongo database.
24
+ # A MongoDB database.
25
25
  class DB
26
26
 
27
27
  SYSTEM_NAMESPACE_COLLECTION = "system.namespaces"
@@ -49,53 +49,19 @@ module Mongo
49
49
  # The Mongo::Connection instance connecting to the MongoDB server.
50
50
  attr_reader :connection
51
51
 
52
- # An array of [host, port] pairs.
53
- attr_reader :nodes
54
-
55
- # The logger instance if :logger is passed to initialize.
56
- attr_reader :logger
57
-
58
- # The primary key factory object (or +nil+).
59
- attr_reader :pk_factory
60
-
61
- def pk_factory=(pk_factory)
62
- raise "error: can not change PK factory" if @pk_factory
63
- @pk_factory = pk_factory
64
- end
65
-
66
52
  # Instances of DB are normally obtained by calling Mongo#db.
67
53
  #
68
- # db_name :: The database name
69
- #
70
- # nodes :: An array of [host, port] pairs. See Connection#new, which offers
71
- # a more flexible way of defining nodes.
72
- #
73
- # options :: A hash of options.
74
- #
75
- # Options:
76
- #
77
- # :strict :: If true, collections must exist to be accessed and must
78
- # not exist to be created. See #collection and #create_collection.
79
- #
80
- # :pk :: A primary key factory object that must respond to :create_pk,
81
- # which should take a hash and return a hash which merges the
82
- # original hash with any primary key fields the factory wishes
83
- # to inject. (NOTE: if the object already has a primary key,
84
- # the factory should not inject a new key; this means that the
85
- # object is being used in a repsert but it already exists.) The
86
- # idea here is that when ever a record is inserted, the :pk
87
- # object's +create_pk+ method will be called and the new hash
88
- # returned will be inserted.
54
+ # @param [String] db_name the database name.
55
+ # @param [Mongo::Connection] connection a connection object pointing to MongoDB. Note
56
+ # that databases are usually instantiated via the Connection class. See the examples below.
89
57
  #
90
- # :slave_ok :: Only used if +nodes+ contains only one host/port. If
91
- # false, when connecting to that host/port we check to
92
- # see if the server is the master. If it is not, an error
93
- # is thrown.
58
+ # @option options [Boolean] strict (False) If true, collections must exist to be accessed and must
59
+ # not exist to be created. See DB#collection and DB#create_collection.
94
60
  #
95
- # :logger :: Optional Logger instance to which driver usage information
96
- # will be logged.
97
- #
98
- # :auto_reconnect :: DEPRECATED. See http://www.mongodb.org/display/DOCS/Replica+Pairs+in+Ruby
61
+ # @option options [Object, #create_pk(doc)] pk (Mongo::ObjectID) A primary key factory object,
62
+ # which should take a hash and return a hash which merges the original hash with any primary key
63
+ # fields the factory wishes to inject. (NOTE: if the object already has a primary key,
64
+ # the factory should not inject a new key).
99
65
  def initialize(db_name, connection, options={})
100
66
  @name = validate_db_name(db_name)
101
67
  @connection = connection
@@ -103,9 +69,13 @@ module Mongo
103
69
  @pk_factory = options[:pk]
104
70
  end
105
71
 
106
- # Returns true if +username+ has +password+ in
107
- # +SYSTEM_USER_COLLECTION+. +name+ is username, +password+ is
108
- # plaintext password.
72
+ # Authenticate with the given username and password. Note that mongod
73
+ # must be started with the --auth option for authentication to be enabled.
74
+ #
75
+ # @param [String] username
76
+ # @param [String] password
77
+ #
78
+ # @return [Boolean]
109
79
  def authenticate(username, password)
110
80
  doc = command(:getnonce => 1)
111
81
  raise "error retrieving nonce: #{doc}" unless ok?(doc)
@@ -120,111 +90,148 @@ module Mongo
120
90
  end
121
91
 
122
92
  # Deauthorizes use for this database for this connection.
93
+ #
94
+ # @raise [MongoDBError] if logging out fails.
95
+ #
96
+ # @return [Boolean]
123
97
  def logout
124
98
  doc = command(:logout => 1)
125
- raise "error logging out: #{doc.inspect}" unless ok?(doc)
99
+ return true if ok?(doc)
100
+ raise MongoDBError, "error logging out: #{doc.inspect}"
126
101
  end
127
102
 
128
- # Returns an array of collection names in this database.
103
+ # Get an array of collection names in this database.
104
+ #
105
+ # @return [Array]
129
106
  def collection_names
130
107
  names = collections_info.collect { |doc| doc['name'] || '' }
131
108
  names = names.delete_if {|name| name.index(@name).nil? || name.index('$')}
132
109
  names.map {|name| name.sub(@name + '.', '')}
133
110
  end
134
111
 
135
- # Retuns an array of Collection instances, one for each collection in this
136
- # database.
112
+ # Get an array of Collection instances, one for each collection in this database.
113
+ #
114
+ # @return [Array<Mongo::Collection>]
137
115
  def collections
138
116
  collection_names.map do |collection_name|
139
117
  Collection.new(self, collection_name)
140
118
  end
141
119
  end
142
120
 
143
- # Returns a cursor over query result hashes. Each hash contains a
144
- # 'name' string and optionally an 'options' hash. If +coll_name+ is
145
- # specified, an array of length 1 is returned.
121
+ # Get info on system namespaces (collections). This method returns
122
+ # a cursor which can be iterated over. For each collection, a hash
123
+ # will be yielded containing a 'name' string and, optionally, an 'options' hash.
124
+ #
125
+ # @param [String] coll_name return info for the specifed collection only.
126
+ #
127
+ # @return [Mongo::Cursor]
146
128
  def collections_info(coll_name=nil)
147
129
  selector = {}
148
130
  selector[:name] = full_collection_name(coll_name) if coll_name
149
131
  Cursor.new(Collection.new(self, SYSTEM_NAMESPACE_COLLECTION), :selector => selector)
150
132
  end
151
133
 
152
- # Create a collection. If +strict+ is false, will return existing or
134
+ # Create a collection.
135
+ #
153
136
  # new collection. If +strict+ is true, will raise an error if
154
137
  # collection +name+ already exists.
155
138
  #
156
- # Options is an optional hash:
139
+ # @param [String] name the name of the new collection.
140
+ #
141
+ # @option options [Boolean] :capped (False) created a capped collection.
142
+ #
143
+ # @option options [Integer] :size (Nil) If +capped+ is +true+, specifies the maximum number of
144
+ # bytes for the capped collection. If +false+, specifies the number of bytes allocated
145
+ # for the initial extent of the collection.
157
146
  #
158
- # :capped :: Boolean. If not specified, capped is +false+.
147
+ # @option options [Integer] :max (Nil) If +capped+ is +true+, indicates the maximum number of records
148
+ # in a capped collection.
159
149
  #
160
- # :size :: If +capped+ is +true+, specifies the maximum number of
161
- # bytes. If +false+, specifies the initial extent of the
162
- # collection.
150
+ # @raise [MongoDBError] raised under two conditions: either we're in +strict+ mode and the collection
151
+ # already exists or collection creation fails on the server.
163
152
  #
164
- # :max :: Max number of records in a capped collection. Optional.
153
+ # @return [Mongo::Collection]
165
154
  def create_collection(name, options={})
166
- # First check existence
155
+ # Does the collection already exist?
167
156
  if collection_names.include?(name)
168
157
  if strict?
169
- raise "Collection #{name} already exists. Currently in strict mode."
158
+ raise MongoDBError, "Collection #{name} already exists. Currently in strict mode."
170
159
  else
171
160
  return Collection.new(self, name)
172
161
  end
173
162
  end
174
163
 
175
- # Create new collection
164
+ # Create a new collection.
176
165
  oh = OrderedHash.new
177
166
  oh[:create] = name
178
167
  doc = command(oh.merge(options || {}))
179
168
  ok = doc['ok']
180
169
  return Collection.new(self, name, @pk_factory) if ok.kind_of?(Numeric) && (ok.to_i == 1 || ok.to_i == 0)
181
- raise "Error creating collection: #{doc.inspect}"
170
+ raise MongoDBError, "Error creating collection: #{doc.inspect}"
182
171
  end
183
172
 
173
+ # @deprecated all the admin methods are now included in the DB class.
184
174
  def admin
175
+ warn "DB#admin has been DEPRECATED. All the admin functions are now available in the DB class itself."
185
176
  Admin.new(self)
186
177
  end
187
178
 
188
- # Return a collection. If +strict+ is false, will return existing or
189
- # new collection. If +strict+ is true, will raise an error if
190
- # collection +name+ does not already exists.
179
+ # Get a collection by name.
180
+ #
181
+ # @param [String] name the collection name.
182
+ #
183
+ # @raise [MongoDBError] if collection does not already exist and we're in +strict+ mode.
184
+ #
185
+ # @return [Mongo::Collection]
191
186
  def collection(name)
192
187
  return Collection.new(self, name, @pk_factory) if !strict? || collection_names.include?(name)
193
- raise "Collection #{name} doesn't exist. Currently in strict mode."
188
+ raise MongoDBError, "Collection #{name} doesn't exist. Currently in strict mode."
194
189
  end
195
190
  alias_method :[], :collection
196
191
 
197
- # Drop collection +name+. Returns +true+ on success or if the
198
- # collection does not exist, +false+ otherwise.
192
+ # Drop a collection by +name+.
193
+ #
194
+ # @param [String] name
195
+ #
196
+ # @return [Boolean] True on success or if the collection names doesn't exist.
199
197
  def drop_collection(name)
200
198
  return true unless collection_names.include?(name)
201
199
 
202
200
  ok?(command(:drop => name))
203
201
  end
204
202
 
205
- # Returns the error message from the most recently executed database
206
- # operation for this connection, or +nil+ if there was no error.
203
+ # Get the error message from the most recently executed database
204
+ # operation for this connection.
205
+ #
206
+ # @return [String, Nil] either the text describing the error or nil if no
207
+ # error has occurred.
207
208
  def error
208
209
  doc = command(:getlasterror => 1)
209
- raise "error retrieving last error: #{doc}" unless ok?(doc)
210
+ raise MongoDBError, "error retrieving last error: #{doc}" unless ok?(doc)
210
211
  doc['err']
211
212
  end
212
213
 
213
214
  # Get status information from the last operation on this connection.
215
+ #
216
+ # @return [Hash] a hash representing the status of the last db op.
214
217
  def last_status
215
218
  command(:getlasterror => 1)
216
219
  end
217
220
 
218
- # Returns +true+ if an error was caused by the most recently executed
221
+ # Return +true+ if an error was caused by the most recently executed
219
222
  # database operation.
223
+ #
224
+ # @return [Boolean]
220
225
  def error?
221
226
  error != nil
222
227
  end
223
228
 
224
- # Get the most recent error to have occured on this database
229
+ # Get the most recent error to have occured on this database.
225
230
  #
226
- # Only returns errors that have occured since the last call to
231
+ # This command only returns errors that have occured since the last call to
227
232
  # DB#reset_error_history - returns +nil+ if there is no such error.
233
+ #
234
+ # @return [String, Nil] the text of the error or +nil+ if no error has occurred.
228
235
  def previous_error
229
236
  error = command(:getpreverror => 1)
230
237
  if error["err"]
@@ -238,28 +245,41 @@ module Mongo
238
245
  #
239
246
  # Calls to DB#previous_error will only return errors that have occurred
240
247
  # since the most recent call to this method.
248
+ #
249
+ # @return [Hash]
241
250
  def reset_error_history
242
251
  command(:reseterror => 1)
243
252
  end
244
253
 
254
+ # @deprecated please use Collection#find to create queries.
255
+ #
245
256
  # Returns a Cursor over the query results.
246
257
  #
247
258
  # Note that the query gets sent lazily; the cursor calls
248
- # #send_query_message when needed. If the caller never requests an
259
+ # Connection#send_message when needed. If the caller never requests an
249
260
  # object from the cursor, the query never gets sent.
250
261
  def query(collection, query, admin=false)
251
262
  Cursor.new(self, collection, query, admin)
252
263
  end
253
264
 
254
- # Dereference a DBRef, getting the document it points to.
265
+ # Dereference a DBRef, returning the document it points to.
266
+ #
267
+ # @param [Mongo::DBRef] dbref
268
+ #
269
+ # @return [Hash] the document indicated by the db reference.
270
+ #
271
+ # @see http://www.mongodb.org/display/DOCS/DB+Ref MongoDB DBRef spec.
255
272
  def dereference(dbref)
256
273
  collection(dbref.namespace).find_one("_id" => dbref.object_id)
257
274
  end
258
275
 
259
- # Evaluate a JavaScript expression on MongoDB.
260
- # +code+ should be a string or Code instance containing a JavaScript
261
- # expression. Additional arguments will be passed to that expression
262
- # when it is run on the server.
276
+ # Evaluate a JavaScript expression in MongoDB.
277
+ #
278
+ # @param [String, Code] code a JavaScript expression to evaluate server-side.
279
+ # @param [Integer, Hash] args any additional argument to be passed to the +code+ expression when
280
+ # it's run on the server.
281
+ #
282
+ # @return [String] the return value of the function.
263
283
  def eval(code, *args)
264
284
  if not code.is_a? Code
265
285
  code = Code.new(code)
@@ -273,31 +293,46 @@ module Mongo
273
293
  raise OperationFailure, "eval failed: #{doc['errmsg']}"
274
294
  end
275
295
 
276
- # Rename collection +from+ to +to+. Meant to be called by
277
- # Collection#rename.
296
+ # Rename a collection.
297
+ #
298
+ # @param [String] from original collection name.
299
+ # @param [String] to new collection name.
300
+ #
301
+ # @return [True] returns +true+ on success.
302
+ #
303
+ # @raise MongoDBError if there's an error renaming the collection.
278
304
  def rename_collection(from, to)
279
305
  oh = OrderedHash.new
280
306
  oh[:renameCollection] = "#{@name}.#{from}"
281
307
  oh[:to] = "#{@name}.#{to}"
282
308
  doc = command(oh, true)
283
- raise "Error renaming collection: #{doc.inspect}" unless ok?(doc)
309
+ ok?(doc) || raise(MongoDBError, "Error renaming collection: #{doc.inspect}")
284
310
  end
285
311
 
286
- # Drop index +name+ from +collection_name+. Normally called from
312
+ # Drop an index from a given collection. Normally called from
287
313
  # Collection#drop_index or Collection#drop_indexes.
288
- def drop_index(collection_name, name)
314
+ #
315
+ # @param [String] collection_name
316
+ # @param [String] index_name
317
+ #
318
+ # @return [True] returns +true+ on success.
319
+ #
320
+ # @raise MongoDBError if there's an error renaming the collection.
321
+ def drop_index(collection_name, index_name)
289
322
  oh = OrderedHash.new
290
323
  oh[:deleteIndexes] = collection_name
291
- oh[:index] = name
324
+ oh[:index] = index_name
292
325
  doc = command(oh)
293
- raise "Error with drop_index command: #{doc.inspect}" unless ok?(doc)
326
+ ok?(doc) || raise(MongoDBError, "Error with drop_index command: #{doc.inspect}")
294
327
  end
295
328
 
296
- # Get information on the indexes for the collection +collection_name+.
297
- # Normally called by Collection#index_information. Returns a hash where
298
- # the keys are index names (as returned by Collection#create_index and
299
- # the values are lists of [key, direction] pairs specifying the index
300
- # (as passed to Collection#create_index).
329
+ # Get information on the indexes for the given collection.
330
+ # Normally called by Collection#index_information.
331
+ #
332
+ # @param [String] collection_name
333
+ #
334
+ # @return [Hash] keys are index names and the values are lists of [key, direction] pairs
335
+ # defining the index.
301
336
  def index_information(collection_name)
302
337
  sel = {:ns => full_collection_name(collection_name)}
303
338
  info = {}
@@ -307,49 +342,50 @@ module Mongo
307
342
  info
308
343
  end
309
344
 
310
- # Create a new index on +collection_name+. +field_or_spec+
311
- # should be either a single field name or a Array of [field name,
312
- # direction] pairs. Directions should be specified as
313
- # Mongo::ASCENDING or Mongo::DESCENDING. Normally called
314
- # by Collection#create_index. If +unique+ is true the index will
315
- # enforce a uniqueness constraint.
345
+ # Create a new index on the given collection.
346
+ # Normally called by Collection#create_index.
347
+ #
348
+ # @param [String] collection_name
349
+ # @param [String, Array] field_or_spec either either a single field name
350
+ # or an array of [field name, direction] pairs. Directions should be specified as
351
+ # Mongo::ASCENDING or Mongo::DESCENDING.
352
+ # @param [Boolean] unique if +true+, the created index will enforce a uniqueness constraint.
353
+ #
354
+ # @return [String] the name of the index created.
316
355
  def create_index(collection_name, field_or_spec, unique=false)
317
356
  self.collection(collection_name).create_index(field_or_spec, unique)
318
357
  end
319
358
 
320
- # Return +true+ if +doc+ contains an 'ok' field with the value 1.
359
+ # Return +true+ if the supplied +doc+ contains an 'ok' field with the value 1.
360
+ #
361
+ # @param [Hash] doc
362
+ #
363
+ # @return [Boolean]
321
364
  def ok?(doc)
322
365
  ok = doc['ok']
323
366
  ok.kind_of?(Numeric) && ok.to_i == 1
324
367
  end
325
368
 
326
- # DB commands need to be ordered, so selector must be an OrderedHash
327
- # (or a Hash with only one element). What DB commands really need is
328
- # that the "command" key be first.
329
- def command(selector, use_admin_db=false, sock=nil)
330
- if !selector.kind_of?(OrderedHash)
331
- if !selector.kind_of?(Hash) || selector.keys.length > 1
332
- raise "command must be given an OrderedHash when there is more than one key"
333
- end
334
- end
335
-
336
- cursor = Cursor.new(Collection.new(self, SYSTEM_COMMAND_COLLECTION), :admin => use_admin_db, :limit => -1, :selector => selector, :socket => sock)
337
- cursor.next_document
338
- end
339
-
340
- # Sends a command to the database.
369
+ # Send a command to the database.
370
+ #
371
+ # Note: DB commands must start with the "command" key. For this reason,
372
+ # any selector containing more than one key must be an OrderedHash.
373
+ #
374
+ # It may be of interest hat a command in MongoDB is technically a kind of query
375
+ # that occurs on the system command collection ($cmd).
341
376
  #
342
- # :selector (required) :: An OrderedHash, or a standard Hash with just one
377
+ # @param [OrderedHash, Hash] selector an OrderedHash, or a standard Hash with just one
343
378
  # key, specifying the command to be performed.
344
379
  #
345
- # :admin (optional) :: If true, the command will be executed on the admin
380
+ # @param [Boolean] admin If +true+, the command will be executed on the admin
346
381
  # collection.
347
382
  #
348
- # :check_response (optional) :: If true, will raise an exception if the
383
+ # @param [Boolean] check_response If +true+, will raise an exception if the
349
384
  # command fails.
350
385
  #
351
- # Note: DB commands must start with the "command" key. For this reason,
352
- # any selector containing more than one key must be an OrderedHash.
386
+ # @param [Socket] sock a socket to use. This is mainly for internal use.
387
+ #
388
+ # @return [Hash]
353
389
  def command(selector, admin=false, check_response=false, sock=nil)
354
390
  raise MongoArgumentError, "command must be given a selector" unless selector.is_a?(Hash) && !selector.empty?
355
391
  if selector.class.eql?(Hash) && selector.keys.length > 1
@@ -366,16 +402,104 @@ module Mongo
366
402
  end
367
403
  end
368
404
 
369
- # DEPRECATED: please use DB#command instead.
405
+ # @deprecated please use DB#command instead.
370
406
  def db_command(*args)
371
407
  warn "DB#db_command has been DEPRECATED. Please use DB#command instead."
372
408
  command(args[0], args[1])
373
409
  end
374
410
 
411
+ # A shortcut returning db plus dot plus collection name.
412
+ #
413
+ # @param [String] collection_name
414
+ #
415
+ # @return [String]
375
416
  def full_collection_name(collection_name)
376
417
  "#{@name}.#{collection_name}"
377
418
  end
378
419
 
420
+ # The primary key factory object (or +nil+).
421
+ #
422
+ # @return [Object, Nil]
423
+ def pk_factory
424
+ @pk_factory
425
+ end
426
+
427
+ # Specify a primary key factory if not already set.
428
+ #
429
+ # @raise [MongoArgumentError] if the primary key factory has already been set.
430
+ def pk_factory=(pk_factory)
431
+ if @pk_factory
432
+ raise MongoArgumentError, "Cannot change primary key factory once it's been set"
433
+ end
434
+
435
+ @pk_factory = pk_factory
436
+ end
437
+
438
+ # Return the current database profiling level. If profiling is enabled, you can
439
+ # get the results using DB#profiling_info.
440
+ #
441
+ # @return [Symbol] :off, :slow_only, or :all
442
+ def profiling_level
443
+ oh = OrderedHash.new
444
+ oh[:profile] = -1
445
+ doc = command(oh)
446
+ raise "Error with profile command: #{doc.inspect}" unless ok?(doc) && doc['was'].kind_of?(Numeric)
447
+ case doc['was'].to_i
448
+ when 0
449
+ :off
450
+ when 1
451
+ :slow_only
452
+ when 2
453
+ :all
454
+ else
455
+ raise "Error: illegal profiling level value #{doc['was']}"
456
+ end
457
+ end
458
+
459
+ # Set this database's profiling level. If profiling is enabled, you can
460
+ # get the results using DB#profiling_info.
461
+ #
462
+ # @param [Symbol] level acceptable options are +:off+, +:slow_only+, or +:all+.
463
+ def profiling_level=(level)
464
+ oh = OrderedHash.new
465
+ oh[:profile] = case level
466
+ when :off
467
+ 0
468
+ when :slow_only
469
+ 1
470
+ when :all
471
+ 2
472
+ else
473
+ raise "Error: illegal profiling level value #{level}"
474
+ end
475
+ doc = command(oh)
476
+ ok?(doc) || raise(MongoDBError, "Error with profile command: #{doc.inspect}")
477
+ end
478
+
479
+ # Get the current profiling information.
480
+ #
481
+ # @return [Array] a list of documents containing profiling information.
482
+ def profiling_info
483
+ Cursor.new(Collection.new(self, DB::SYSTEM_PROFILE_COLLECTION), :selector => {}).to_a
484
+ end
485
+
486
+ # Validate a named collection.
487
+ #
488
+ # @param [String] name the collection name.
489
+ #
490
+ # @return [Hash] validation information.
491
+ #
492
+ # @raise [MongoDBError] if the command fails or there's a problem with the validation
493
+ # data, or if the collection is invalid.
494
+ def validate_collection(name)
495
+ doc = command(:validate => name)
496
+ raise MongoDBError, "Error with validate command: #{doc.inspect}" unless ok?(doc)
497
+ result = doc['result']
498
+ raise MongoDBError, "Error with validation data: #{doc.inspect}" unless result.kind_of?(String)
499
+ raise MongoDBError, "Error: invalid collection #{name}: #{doc.inspect}" if result =~ /\b(exception|corrupt)\b/i
500
+ doc
501
+ end
502
+
379
503
  private
380
504
 
381
505
  def hash_password(username, plaintext)