mongo 1.10.0.rc0 → 1.10.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/VERSION +1 -1
  5. data/lib/mongo/bulk_write_collection_view.rb +31 -3
  6. data/lib/mongo/collection.rb +69 -25
  7. data/lib/mongo/collection_writer.rb +3 -2
  8. data/lib/mongo/connection/node.rb +5 -0
  9. data/lib/mongo/cursor.rb +4 -1
  10. data/lib/mongo/db.rb +23 -41
  11. data/lib/mongo/functional.rb +2 -0
  12. data/lib/mongo/functional/authentication.rb +18 -3
  13. data/lib/mongo/functional/sasl_java.rb +48 -0
  14. data/lib/mongo/functional/uri_parser.rb +62 -50
  15. data/lib/mongo/mongo_client.rb +24 -9
  16. data/lib/mongo/mongo_replica_set_client.rb +16 -5
  17. data/lib/mongo/networking.rb +3 -3
  18. data/lib/mongo/utils/conversions.rb +2 -1
  19. data/test/functional/authentication_test.rb +6 -1
  20. data/test/functional/bulk_api_stress_test.rb +133 -0
  21. data/test/functional/bulk_write_collection_view_test.rb +573 -226
  22. data/test/functional/client_test.rb +3 -1
  23. data/test/functional/collection_test.rb +336 -17
  24. data/test/functional/conversions_test.rb +32 -0
  25. data/test/functional/cursor_test.rb +3 -3
  26. data/test/functional/db_api_test.rb +2 -2
  27. data/test/functional/db_test.rb +24 -0
  28. data/test/functional/uri_test.rb +49 -32
  29. data/test/helpers/test_unit.rb +8 -0
  30. data/test/replica_set/authentication_test.rb +5 -1
  31. data/test/replica_set/client_test.rb +5 -4
  32. data/test/replica_set/max_values_test.rb +6 -0
  33. data/test/shared/authentication/basic_auth_shared.rb +101 -30
  34. data/test/shared/authentication/bulk_api_auth_shared.rb +259 -0
  35. data/test/shared/authentication/gssapi_shared.rb +164 -0
  36. data/test/shared/ssl_shared.rb +49 -27
  37. data/test/unit/client_test.rb +4 -2
  38. data/test/unit/connection_test.rb +4 -2
  39. data/test/unit/cursor_test.rb +12 -0
  40. data/test/unit/db_test.rb +6 -0
  41. metadata +27 -20
  42. metadata.gz.sig +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8cd7d73987a4420fcb416fb0cfa6c9f711b9dc00
4
- data.tar.gz: ec9b4e834cfc4169a1035ad301c87ff2684639ea
3
+ metadata.gz: 280fdca0cfd2705bb339614159fa2a9ac3a6646f
4
+ data.tar.gz: 1656445245aa6d3c58729875b7f2229416a7cc48
5
5
  SHA512:
6
- metadata.gz: 09f5296283a06b7d08619f347f8723e7423e0b126d29fbfbaf1c38594e0b5d3a65e0b71de1161882d61f98186bd544c80f5fe8dfc3ae3b09ad25acf98e9611cb
7
- data.tar.gz: 4bde563936a1ff51ee037bb4289d8057316fed86e9b5e009612f85f7c41552e2746698a6c5114277783d179226703d7d1dfbcccfb12d8b315c7549f3dcd8db98
6
+ metadata.gz: a5833530677b1c66c31d06ce0999b1aab3a0541a6cea1b5c15b71c3bc0a09c0b8adbe8585294c4095ac992eea171b401cdfc70c8d9505dda4a8bbccb29727794
7
+ data.tar.gz: 3a44a8940281e6fc17a3862883881ab37f35b588079afecc47b5fb07ede6a30298fa91e6052bac1d53d386fad9b843edbaecefac7c62d326c1146edd30ef8337
checksums.yaml.gz.sig CHANGED
Binary file
data.tar.gz.sig CHANGED
Binary file
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.10.0.rc0
1
+ 1.10.0.rc1
@@ -18,8 +18,9 @@ module Mongo
18
18
  class BulkWriteCollectionView
19
19
  include Mongo::WriteConcern
20
20
 
21
- DEFAULT_OP_ARGS = {:q => {}}
21
+ DEFAULT_OP_ARGS = {:q => nil}
22
22
  MULTIPLE_ERRORS_MSG = "batch item errors occurred"
23
+ EMPTY_BATCH_MSG = "batch is empty"
23
24
 
24
25
  attr_reader :collection, :options, :ops, :op_args
25
26
 
@@ -91,6 +92,21 @@ module Mongo
91
92
 
92
93
  # Modify the query selector for subsequent bulk write operations.
93
94
  # The default query selector on creation of the bulk write view is {}.
95
+ # For operations that require a query selector, find() must be set
96
+ # per operation, or set once for all operations on the bulk object.
97
+ # For example, these operations:
98
+ #
99
+ # bulk.find({"a" => 2}).update({"$inc" => {"x" => 2}})
100
+ # bulk.find({"a" => 2}).update({"$set" => {"b" => 3}})
101
+ #
102
+ # may be rewritten as:
103
+ #
104
+ # bulk = find({"a" => 2})
105
+ # bulk.update({"$inc" => {"x" => 2}})
106
+ # bulk.update({"$set" => {"b" => 3}})
107
+ #
108
+ # Note that modifying the query selector in this way will not affect
109
+ # operations that do not use a query selector, like insert().
94
110
  #
95
111
  # @param [Hash] q the query selector
96
112
  #
@@ -200,6 +216,7 @@ module Mongo
200
216
  #
201
217
  # @return [BulkWriteCollectionView]
202
218
  def execute(opts = {})
219
+ raise MongoArgumentError, EMPTY_BATCH_MSG if @ops.empty?
203
220
  write_concern = get_write_concern(opts, @collection)
204
221
  @ops.each_with_index{|op, index| op.last.merge!(:ord => index)} # infuse ordinal here to avoid issues with upsert
205
222
  if @collection.db.connection.use_write_command?(write_concern)
@@ -208,7 +225,7 @@ module Mongo
208
225
  errors, exchanges = @collection.operation_writer.bulk_execute(@ops, @options, opts)
209
226
  end
210
227
  @ops = []
211
- return true if exchanges.first[:response] == true # w 0 without GLE
228
+ return true if errors.empty? && (exchanges.empty? || exchanges.first[:response] == true) # w 0 without GLE
212
229
  result = merge_result(errors, exchanges)
213
230
  raise BulkWriteError.new(MULTIPLE_ERRORS_MSG, Mongo::ErrorCode::MULTIPLE_ERRORS_OCCURRED, result) if !errors.empty? || result["writeConcernError"]
214
231
  result
@@ -229,6 +246,14 @@ module Mongo
229
246
  h[key] = h.fetch(key, 0) + n
230
247
  end
231
248
 
249
+ def nil_tally(h, key, n)
250
+ if !h.has_key?(key)
251
+ h[key] = n
252
+ elsif h[key]
253
+ h[key] = n ? h[key] + n : n
254
+ end
255
+ end
256
+
232
257
  def append(h, key, obj)
233
258
  h[key] = h.fetch(key, []) << obj
234
259
  end
@@ -259,6 +284,7 @@ module Mongo
259
284
  end
260
285
  exchanges.each do |exchange|
261
286
  response = exchange[:response]
287
+ next unless response
262
288
  ok += response["ok"].to_i
263
289
  n = response["n"] || 0
264
290
  op_type = exchange[:op_type]
@@ -274,7 +300,7 @@ module Mongo
274
300
  end
275
301
  tally(result, "nUpserted", n_upserted) if n_upserted > 0
276
302
  tally(result, "nMatched", n - n_upserted)
277
- tally(result, "nModified", response["nModified"] || n - n_upserted)
303
+ nil_tally(result, "nModified", response["nModified"])
278
304
  elsif op_type == :delete
279
305
  tally(result, "nRemoved", n)
280
306
  end
@@ -300,6 +326,7 @@ module Mongo
300
326
  end
301
327
  append(result, "writeConcernError", merge_index(writeConcernError, exchange)) if writeConcernError
302
328
  end
329
+ result.delete("nModified") if result.has_key?("nModified") && !result["nModified"]
303
330
  result.merge!("ok" => [ok + result["n"], 1].min)
304
331
  end
305
332
 
@@ -313,6 +340,7 @@ module Mongo
313
340
  end
314
341
 
315
342
  def op_push(op)
343
+ raise MongoArgumentError, "non-nil query must be set via find" if op.first != :insert && !op.last[:q]
316
344
  @ops << op
317
345
  self
318
346
  end
@@ -39,10 +39,16 @@ module Mongo
39
39
  # @param [DB] db a MongoDB database instance.
40
40
  #
41
41
  # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
42
- # should be acknowledged
43
- # @option opts [Boolean] :j (false) Set journal acknowledgement
44
- # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
45
- # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
42
+ # should be acknowledged.
43
+ # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
44
+ # @option opts [Boolean] :j (false) If true, block until write operations have been committed
45
+ # to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
46
+ # ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
47
+ # fail with an exception if this option is used when the server is running without journaling.
48
+ # @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
49
+ # the server has synced all data files to disk. If the server is running with journaling, this acts the same as
50
+ # the 'j' option, blocking until write operations have been committed to the journal.
51
+ # Cannot be used in combination with 'j'.
46
52
  #
47
53
  # Notes about write concern:
48
54
  # These write concern options will be used for insert, update, and remove methods called on this
@@ -332,11 +338,18 @@ module Mongo
332
338
  #
333
339
  # @return [ObjectId] the _id of the saved document.
334
340
  #
335
- # @option opts [Hash] :w, :j, :wtimeout, :fsync Set the write concern for this operation.
336
- # :w > 0 will run a +getlasterror+ command on the database to report any assertion.
337
- # :j will confirm a write has been committed to the journal,
338
- # :wtimeout specifies how long to wait for write confirmation,
339
- # :fsync will confirm that a write has been fsynced.
341
+ # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
342
+ # should be acknowledged.
343
+ # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
344
+ # @option opts [Boolean] :j (false) If true, block until write operations have been committed
345
+ # to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
346
+ # ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
347
+ # fail with an exception if this option is used when the server is running without journaling.
348
+ # @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
349
+ # the server has synced all data files to disk. If the server is running with journaling, this acts the same as
350
+ # the 'j' option, blocking until write operations have been committed to the journal.
351
+ # Cannot be used in combination with 'j'.
352
+ #
340
353
  # Options provided here will override any write concern options set on this collection,
341
354
  # its database object, or the current connection. See the options
342
355
  # for DB#get_last_error.
@@ -365,10 +378,16 @@ module Mongo
365
378
  # Return this result format only when :collect_on_error is true.
366
379
  #
367
380
  # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
368
- # should be acknowledged
369
- # @option opts [Boolean] :j (false) Set journal acknowledgement
370
- # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
371
- # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
381
+ # should be acknowledged.
382
+ # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
383
+ # @option opts [Boolean] :j (false) If true, block until write operations have been committed
384
+ # to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
385
+ # ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
386
+ # fail with an exception if this option is used when the server is running without journaling.
387
+ # @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
388
+ # the server has synced all data files to disk. If the server is running with journaling, this acts the same as
389
+ # the 'j' option, blocking until write operations have been committed to the journal.
390
+ # Cannot be used in combination with 'j'.
372
391
  #
373
392
  # Notes on write concern:
374
393
  # Options provided here will override any write concern options set on this collection,
@@ -408,10 +427,16 @@ module Mongo
408
427
  # If specified, only matching documents will be removed.
409
428
  #
410
429
  # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
411
- # should be acknowledged
412
- # @option opts [Boolean] :j (false) Set journal acknowledgement
413
- # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
414
- # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
430
+ # should be acknowledged.
431
+ # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
432
+ # @option opts [Boolean] :j (false) If true, block until write operations have been committed
433
+ # to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
434
+ # ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
435
+ # fail with an exception if this option is used when the server is running without journaling.
436
+ # @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
437
+ # the server has synced all data files to disk. If the server is running with journaling, this acts the same as
438
+ # the 'j' option, blocking until write operations have been committed to the journal.
439
+ # Cannot be used in combination with 'j'.
415
440
  # @option opts [Integer] :limit (0) Set limit option, currently only 0 for all or 1 for just one.
416
441
  #
417
442
  # Notes on write concern:
@@ -448,10 +473,16 @@ module Mongo
448
473
  # @option opts [Boolean] :multi (+false+) update all documents matching the selector, as opposed to
449
474
  # just the first matching document. Note: only works in MongoDB 1.1.3 or later.
450
475
  # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
451
- # should be acknowledged
452
- # @option opts [Boolean] :j (false) Set journal acknowledgement
453
- # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
454
- # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
476
+ # should be acknowledged.
477
+ # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
478
+ # @option opts [Boolean] :j (false) If true, block until write operations have been committed
479
+ # to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
480
+ # ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
481
+ # fail with an exception if this option is used when the server is running without journaling.
482
+ # @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
483
+ # the server has synced all data files to disk. If the server is running with journaling, this acts the same as
484
+ # the 'j' option, blocking until write operations have been committed to the journal.
485
+ # Cannot be used in combination with 'j'.
455
486
  #
456
487
  # Notes on write concern:
457
488
  # Options provided here will override any write concern options set on this collection,
@@ -626,6 +657,9 @@ module Mongo
626
657
  # @example Define the pipeline as an array of operator hashes:
627
658
  # coll.aggregate([ {"$project" => {"last_name" => 1, "first_name" => 1 }}, {"$match" => {"last_name" => "Jones"}} ])
628
659
  #
660
+ # @example With server version 2.5.1 or newer, pass a cursor option to retrieve unlimited aggregation results:
661
+ # coll.aggregate([ {"$group" => { :_id => "$_id", :count => { "$sum" => "$members" }}} ], :cursor => {} )
662
+ #
629
663
  # @param [Array] pipeline Should be a single array of pipeline operator hashes.
630
664
  #
631
665
  # '$project' Reshapes a document stream by including fields, excluding fields, inserting computed fields,
@@ -649,7 +683,8 @@ module Mongo
649
683
  # on. If $out is specified and :read is not :primary, the aggregation will be rerouted to the primary with
650
684
  # a warning. See Collection#find for more details.
651
685
  # @option opts [String] :comment (nil) a comment to include in profiling logs
652
- # @option opts [Hash] :cursor cursor options for aggregation
686
+ # @option opts [Hash] :cursor return a cursor object instead of an Array. Takes an optional batchSize parameter
687
+ # to specify the maximum size, in documents, of the first batch returned.
653
688
  #
654
689
  # @return [Array] An Array with the aggregate command's results.
655
690
  #
@@ -824,7 +859,16 @@ module Mongo
824
859
  end
825
860
  end
826
861
 
827
-
862
+ # Scan this entire collection in parallel.
863
+ # Returns a list of up to num_cursors cursors that can be iterated concurrently. As long as the collection
864
+ # is not modified during scanning, each document appears once in one of the cursors' result sets.
865
+ #
866
+ # @note Requires server version >= 2.5.5
867
+ #
868
+ # @param [Integer] num_cursors the number of cursors to return.
869
+ # @param [Hash] opts
870
+ #
871
+ # @return [Array] An array of up to num_cursors cursors for iterating over the collection.
828
872
  def parallel_scan(num_cursors, opts={})
829
873
  cmd = BSON::OrderedHash.new
830
874
  cmd[:parallelCollectionScan] = self.name
@@ -1082,7 +1126,7 @@ module Mongo
1082
1126
  selector.merge!(opts)
1083
1127
 
1084
1128
  begin
1085
- cmd = BSON::OrderedHash[:createIndexes, @name].merge!(selector)
1129
+ cmd = BSON::OrderedHash[:createIndexes, @name, :indexes, [selector]]
1086
1130
  @db.command(cmd)
1087
1131
  rescue Mongo::OperationFailure => ex
1088
1132
  if ex.error_code == Mongo::ErrorCode::COMMAND_NOT_FOUND || ex.error_code.nil?
@@ -1090,7 +1134,7 @@ module Mongo
1090
1134
  send_write(:insert, nil, selector, false, {:w => 1}, Mongo::DB::SYSTEM_INDEX_COLLECTION)
1091
1135
  else
1092
1136
  raise Mongo::OperationFailure, "Failed to create index #{selector.inspect} with the following error: " +
1093
- "#{e.message}"
1137
+ "#{ex.message}"
1094
1138
  end
1095
1139
  end
1096
1140
 
@@ -28,7 +28,6 @@ module Mongo
28
28
  :update => :updates,
29
29
  :delete => :deletes
30
30
  }
31
- MAX_WRITE_BATCH_SIZE = 1000
32
31
 
33
32
  def initialize(collection)
34
33
  @collection = collection
@@ -36,7 +35,7 @@ module Mongo
36
35
  @db = @collection.db
37
36
  @connection = @db.connection
38
37
  @logger = @connection.logger
39
- @max_write_batch_size = MAX_WRITE_BATCH_SIZE
38
+ @max_write_batch_size = Mongo::MongoClient::DEFAULT_MAX_WRITE_BATCH_SIZE
40
39
  end
41
40
 
42
41
  # common implementation only for new batch write commands (insert, update, delete) and old batch insert
@@ -52,6 +51,7 @@ module Mongo
52
51
  exchanges = []
53
52
  serialized_doc = nil
54
53
  message = BSON::ByteBuffer.new("", max_message_size)
54
+ @max_write_batch_size = @collection.db.connection.max_write_batch_size
55
55
  docs = documents.dup
56
56
  catch(:error) do
57
57
  until docs.empty? || (!errors.empty? && !collect_on_error) # process documents a batch at a time
@@ -99,6 +99,7 @@ module Mongo
99
99
  error_docs = [] # docs with serialization errors
100
100
  errors = []
101
101
  exchanges = []
102
+ @max_write_batch_size = @collection.db.connection.max_write_batch_size
102
103
  @write_batch_size = [documents.size, @max_write_batch_size].min
103
104
  docs = documents.dup
104
105
  until docs.empty?
@@ -193,6 +193,10 @@ module Mongo
193
193
  min_wire_version <= feature && feature <= max_wire_version
194
194
  end
195
195
 
196
+ def max_write_batch_size
197
+ @max_write_batch_size || Mongo::MongoClient::DEFAULT_MAX_WRITE_BATCH_SIZE
198
+ end
199
+
196
200
  protected
197
201
 
198
202
  # Ensure that this node is a healthy member of a replica set.
@@ -229,6 +233,7 @@ module Mongo
229
233
  @max_message_size = config['maxMessageSizeBytes'] || @max_bson_size * MESSAGE_SIZE_FACTOR
230
234
  @max_wire_version = config['maxWireVersion'] || 0
231
235
  @min_wire_version = config['minWireVersion'] || 0
236
+ @max_write_batch_size = config['maxWriteBatchSize'] || Mongo::MongoClient::DEFAULT_MAX_WRITE_BATCH_SIZE
232
237
  end
233
238
  end
234
239
  end
data/lib/mongo/cursor.rb CHANGED
@@ -494,7 +494,10 @@ module Mongo
494
494
  {fields => 1}
495
495
  when Array
496
496
  return nil if fields.length.zero?
497
- fields.inject({}) { |hash, field| hash[field] = 1; hash }
497
+ fields.inject({}) do |hash, field|
498
+ field.is_a?(Hash) ? hash.merge!(field) : hash[field] = 1
499
+ hash
500
+ end
498
501
  when Hash
499
502
  return fields
500
503
  end
data/lib/mongo/db.rb CHANGED
@@ -88,10 +88,16 @@ module Mongo
88
88
  # the factory should not inject a new key).
89
89
  #
90
90
  # @option opts [String, Integer, Symbol] :w (1) Set default number of nodes to which a write
91
- # should be acknowledged
92
- # @option opts [Boolean] :j (false) Set journal acknowledgement
93
- # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout
94
- # @option opts [Boolean] :fsync (false) Set fsync acknowledgement.
91
+ # should be acknowledged.
92
+ # @option opts [Integer] :wtimeout (nil) Set replica set acknowledgement timeout.
93
+ # @option opts [Boolean] :j (false) If true, block until write operations have been committed
94
+ # to the journal. Cannot be used in combination with 'fsync'. Prior to MongoDB 2.6 this option was
95
+ # ignored if the server was running without journaling. Starting with MongoDB 2.6, write operations will
96
+ # fail with an exception if this option is used when the server is running without journaling.
97
+ # @option opts [Boolean] :fsync (false) If true, and the server is running without journaling, blocks until
98
+ # the server has synced all data files to disk. If the server is running with journaling, this acts the same as
99
+ # the 'j' option, blocking until write operations have been committed to the journal.
100
+ # Cannot be used in combination with 'j'.
95
101
  #
96
102
  # Notes on write concern:
97
103
  # These write concern options are propagated to Collection objects instantiated off of this DB. If no
@@ -135,6 +141,8 @@ module Mongo
135
141
  # used to authenticate against a database when the credentials exist
136
142
  # elsewhere.
137
143
  # @param mechanism [String] The authentication mechanism to be used.
144
+ # @param extra [Hash] A optional hash of extra options to be stored with
145
+ # the credential set.
138
146
  #
139
147
  # @note The ability to disable the save_auth option has been deprecated.
140
148
  # With save_auth=false specified, driver authentication behavior during
@@ -144,12 +152,12 @@ module Mongo
144
152
  #
145
153
  # @raise [AuthenticationError] Raised if authentication fails.
146
154
  # @return [Boolean] The result of the authentication operation.
147
- def authenticate(username, password=nil, save_auth=nil, source=nil, mechanism=nil)
155
+ def authenticate(username, password=nil, save_auth=nil, source=nil, mechanism=nil, extra=nil)
148
156
  warn "[DEPRECATED] Disabling the 'save_auth' option no longer has " +
149
157
  "any effect. Please see the API documentation for more details " +
150
158
  "on this change." unless save_auth.nil?
151
159
 
152
- @client.add_auth(self.name, username, password, source, mechanism)
160
+ @client.add_auth(self.name, username, password, source, mechanism, extra)
153
161
  true
154
162
  end
155
163
 
@@ -222,9 +230,9 @@ module Mongo
222
230
  end
223
231
 
224
232
  if user_info.key?('users') && !user_info['users'].empty?
225
- update_user(username, password, opts)
233
+ create_or_update_user(:updateUser, username, password, read_only, opts)
226
234
  else
227
- create_user(username, password, read_only, opts)
235
+ create_or_update_user(:createUser, username, password, read_only, opts)
228
236
  end
229
237
  end
230
238
 
@@ -667,7 +675,7 @@ module Mongo
667
675
  # @param opts [Hash]
668
676
  #
669
677
  # @private
670
- def create_user(username, password, read_only, opts)
678
+ def create_or_update_user(command, username, password, read_only, opts)
671
679
  if read_only || !opts.key?(:roles)
672
680
  warn "Creating a user with the read_only option or without roles is " +
673
681
  "deprecated in MongoDB >= 2.6"
@@ -682,47 +690,21 @@ module Mongo
682
690
 
683
691
  opts = opts.dup
684
692
  pwd = Mongo::Authentication.hash_password(username, password) if password
685
- create_opts = pwd ? { :pwd => pwd } : {}
693
+ cmd_opts = pwd ? { :pwd => pwd } : {}
686
694
  # specify that the server shouldn't digest the password because the driver does
687
- create_opts[:digestPassword] = false
695
+ cmd_opts[:digestPassword] = false
688
696
  unless opts.key?(:roles)
689
697
  if name == 'admin'
690
698
  roles = read_only ? ['readAnyDatabase'] : ['root']
691
699
  else
692
700
  roles = read_only ? ['read'] : ["dbOwner"]
693
701
  end
694
- create_opts[:roles] = roles
702
+ cmd_opts[:roles] = roles
695
703
  end
696
- create_opts[:writeConcern] =
704
+ cmd_opts[:writeConcern] =
697
705
  opts.key?(:writeConcern) ? opts.delete(:writeConcern) : { :w => 1 }
698
- create_opts.merge!(opts)
699
- command({ :createUser => username }, create_opts)
700
- end
701
-
702
- # Update a user.
703
- #
704
- # @param username [String] The username.
705
- # @param password [String] The user's password.
706
- # @param opts [Hash]
707
- #
708
- # @private
709
- def update_user(username, password, opts)
710
- # The password is always salted and hashed by the driver.
711
- if opts.key?(:digestPassword)
712
- raise MongoArgumentError,
713
- "The digestPassword option is not available via DB#add_user. " +
714
- "Use DB#command(:createUser => ...) instead for this option."
715
- end
716
-
717
- opts = opts.dup
718
- pwd = Mongo::Authentication.hash_password(username, password) if password
719
- update_opts = pwd ? { :pwd => pwd } : {}
720
- # specify that the server shouldn't digest the password because the driver does
721
- update_opts[:digestPassword] = false
722
- update_opts[:writeConcern] =
723
- opts.key?(:writeConcern) ? opts.delete(:writeConcern) : { :w => 1 }
724
- update_opts.merge!(opts)
725
- command({ :updateUser => username }, update_opts)
706
+ cmd_opts.merge!(opts)
707
+ command({ command => username }, cmd_opts)
726
708
  end
727
709
 
728
710
  # Create a user in MongoDB versions < 2.5.3.