mongo 2.1.0.rc0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (110) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +5 -2
  3. data.tar.gz.sig +0 -0
  4. data/Rakefile +2 -2
  5. data/lib/mongo.rb +2 -1
  6. data/lib/mongo/address.rb +11 -5
  7. data/lib/mongo/address/ipv4.rb +6 -1
  8. data/lib/mongo/auth/cr/conversation.rb +1 -1
  9. data/lib/mongo/auth/ldap/conversation.rb +1 -1
  10. data/lib/mongo/auth/scram/conversation.rb +1 -1
  11. data/lib/mongo/auth/user/view.rb +2 -2
  12. data/lib/mongo/auth/x509/conversation.rb +1 -1
  13. data/lib/mongo/bulk_write.rb +12 -9
  14. data/lib/mongo/bulk_write/transformable.rb +20 -5
  15. data/lib/mongo/client.rb +11 -11
  16. data/lib/mongo/cluster.rb +2 -2
  17. data/lib/mongo/collection.rb +21 -8
  18. data/lib/mongo/collection/view.rb +1 -0
  19. data/lib/mongo/collection/view/aggregation.rb +11 -5
  20. data/lib/mongo/collection/view/iterable.rb +6 -2
  21. data/lib/mongo/collection/view/map_reduce.rb +39 -5
  22. data/lib/mongo/collection/view/readable.rb +35 -30
  23. data/lib/mongo/collection/view/writable.rb +26 -18
  24. data/lib/mongo/database.rb +12 -2
  25. data/lib/mongo/database/view.rb +4 -3
  26. data/lib/mongo/dbref.rb +4 -4
  27. data/lib/mongo/grid/fs_bucket.rb +8 -1
  28. data/lib/mongo/grid/stream/read.rb +1 -1
  29. data/lib/mongo/index.rb +5 -0
  30. data/lib/mongo/index/view.rb +2 -2
  31. data/lib/mongo/monitoring/command_log_subscriber.rb +9 -3
  32. data/lib/mongo/monitoring/event.rb +1 -0
  33. data/lib/mongo/monitoring/event/command_started.rb +2 -1
  34. data/lib/mongo/monitoring/event/command_succeeded.rb +6 -3
  35. data/lib/mongo/monitoring/event/secure.rb +58 -0
  36. data/lib/mongo/operation.rb +31 -1
  37. data/lib/mongo/operation/commands/collections_info.rb +2 -0
  38. data/lib/mongo/operation/commands/collections_info/result.rb +39 -0
  39. data/lib/mongo/operation/commands/list_indexes/result.rb +2 -1
  40. data/lib/mongo/operation/commands/map_reduce/result.rb +1 -1
  41. data/lib/mongo/operation/read/query.rb +2 -0
  42. data/lib/mongo/operation/read/query/result.rb +40 -0
  43. data/lib/mongo/operation/result.rb +13 -1
  44. data/lib/mongo/operation/write/bulk/delete.rb +2 -2
  45. data/lib/mongo/operation/write/bulk/update.rb +3 -3
  46. data/lib/mongo/operation/write/delete.rb +2 -2
  47. data/lib/mongo/operation/write/update.rb +9 -4
  48. data/lib/mongo/options.rb +1 -0
  49. data/lib/mongo/options/redacted.rb +156 -0
  50. data/lib/mongo/protocol/insert.rb +25 -6
  51. data/lib/mongo/protocol/query.rb +45 -31
  52. data/lib/mongo/protocol/reply.rb +29 -6
  53. data/lib/mongo/protocol/serializers.rb +1 -1
  54. data/lib/mongo/retryable.rb +83 -0
  55. data/lib/mongo/server.rb +16 -3
  56. data/lib/mongo/server/connectable.rb +21 -3
  57. data/lib/mongo/server/connection.rb +38 -4
  58. data/lib/mongo/server/connection_pool.rb +12 -0
  59. data/lib/mongo/server/connection_pool/queue.rb +15 -0
  60. data/lib/mongo/server/monitor/connection.rb +2 -2
  61. data/lib/mongo/server_selector.rb +5 -0
  62. data/lib/mongo/server_selector/selectable.rb +16 -9
  63. data/lib/mongo/socket.rb +6 -2
  64. data/lib/mongo/uri.rb +1 -1
  65. data/lib/mongo/version.rb +1 -1
  66. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +11 -11
  67. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +10 -10
  68. data/spec/mongo/client_spec.rb +101 -18
  69. data/spec/mongo/collection_spec.rb +44 -0
  70. data/spec/mongo/connection_string_spec.rb +36 -58
  71. data/spec/mongo/database_spec.rb +20 -0
  72. data/spec/mongo/grid/fs_bucket_spec.rb +1 -1
  73. data/spec/mongo/grid/stream/write_spec.rb +2 -2
  74. data/spec/mongo/monitoring/event/command_started_spec.rb +26 -0
  75. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +26 -0
  76. data/spec/mongo/monitoring/event/secure_spec.rb +57 -0
  77. data/spec/mongo/operation/commands/aggregate_spec.rb +0 -16
  78. data/spec/mongo/operation/commands/command_spec.rb +0 -18
  79. data/spec/mongo/operation/kill_cursors_spec.rb +0 -16
  80. data/spec/mongo/operation/read/get_more_spec.rb +0 -16
  81. data/spec/mongo/operation/read/query_spec.rb +19 -16
  82. data/spec/mongo/operation/write/bulk/delete_spec.rb +16 -16
  83. data/spec/mongo/operation/write/bulk/update_spec.rb +6 -6
  84. data/spec/mongo/operation/write/command/delete_spec.rb +0 -16
  85. data/spec/mongo/operation/write/command/insert_spec.rb +0 -16
  86. data/spec/mongo/operation/write/command/update_spec.rb +0 -16
  87. data/spec/mongo/operation/write/delete_spec.rb +3 -3
  88. data/spec/mongo/operation/write/update_spec.rb +6 -6
  89. data/spec/mongo/options/redacted_spec.rb +350 -0
  90. data/spec/mongo/protocol/query_spec.rb +15 -1
  91. data/spec/mongo/retryable_spec.rb +147 -0
  92. data/spec/mongo/server/connection_pool/queue_spec.rb +16 -0
  93. data/spec/mongo/server/connection_pool_spec.rb +32 -0
  94. data/spec/mongo/server/connection_spec.rb +37 -0
  95. data/spec/mongo/server_discovery_and_monitoring_spec.rb +24 -59
  96. data/spec/mongo/server_selection_rtt_spec.rb +37 -57
  97. data/spec/mongo/server_selection_spec.rb +2 -0
  98. data/spec/mongo/server_selector/nearest_spec.rb +1 -0
  99. data/spec/mongo/server_selector/primary_preferred_spec.rb +1 -0
  100. data/spec/mongo/server_selector/primary_spec.rb +8 -2
  101. data/spec/mongo/server_selector/secondary_preferred_spec.rb +1 -0
  102. data/spec/mongo/server_selector/secondary_spec.rb +1 -0
  103. data/spec/mongo/server_spec.rb +68 -1
  104. data/spec/mongo/socket/ssl_spec.rb +29 -5
  105. data/spec/mongo/uri_spec.rb +20 -20
  106. data/spec/support/crud.rb +7 -1
  107. data/spec/support/matchers.rb +1 -1
  108. data/spec/support/shared/server_selector.rb +58 -2
  109. metadata +20 -5
  110. metadata.gz.sig +0 -0
@@ -24,8 +24,18 @@ module Mongo
24
24
  extend Forwardable
25
25
  include Enumerable
26
26
  include Immutable
27
- include Iterable
28
27
  include Loggable
28
+ include Retryable
29
+
30
+ # The inline option.
31
+ #
32
+ # @since 2.1.0
33
+ INLINE = 'inline'.freeze
34
+
35
+ # Reroute message.
36
+ #
37
+ # @since 2.1.0
38
+ REROUTE = 'Rerouting the MapReduce operation to the primary server.'.freeze
29
39
 
30
40
  # @return [ View ] view The collection view.
31
41
  attr_reader :view
@@ -42,6 +52,31 @@ module Mongo
42
52
  # Delegate necessary operations to the collection.
43
53
  def_delegators :collection, :database
44
54
 
55
+ # Iterate through documents returned by the map/reduce.
56
+ #
57
+ # @example Iterate through the result of the map/reduce.
58
+ # map_reduce.each do |document|
59
+ # p document
60
+ # end
61
+ #
62
+ # @return [ Enumerator ] The enumerator.
63
+ #
64
+ # @since 2.0.0
65
+ #
66
+ # @yieldparam [ Hash ] Each matching document.
67
+ def each
68
+ @cursor = nil
69
+ write_with_retry do
70
+ server = read.select_server(cluster)
71
+ result = send_initial_query(server)
72
+ @cursor = Cursor.new(view, result, server)
73
+ end
74
+ @cursor.each do |doc|
75
+ yield doc
76
+ end if block_given?
77
+ @cursor.to_enum
78
+ end
79
+
45
80
  # Set or get the finalize function for the operation.
46
81
  #
47
82
  # @example Set the finalize function.
@@ -148,7 +183,7 @@ module Mongo
148
183
  private
149
184
 
150
185
  def inline?
151
- out.nil? || out == { inline: 1 } || out == { 'inline' => 1 }
186
+ out.nil? || out == { inline: 1 } || out == { INLINE => 1 }
152
187
  end
153
188
 
154
189
  def map_reduce_spec
@@ -182,13 +217,12 @@ module Mongo
182
217
  end
183
218
 
184
219
  def secondary_ok?
185
- out.respond_to?(:keys) &&
186
- out.keys.first.to_s.downcase == 'inline'
220
+ out.respond_to?(:keys) && out.keys.first.to_s.downcase == INLINE
187
221
  end
188
222
 
189
223
  def send_initial_query(server)
190
224
  unless valid_server?(server)
191
- log_warn('Rerouting the MapReduce operation to the primary server.')
225
+ log_warn(REROUTE)
192
226
  server = cluster.next_primary
193
227
  end
194
228
  result = initial_query_op.execute(server.context)
@@ -25,17 +25,17 @@ module Mongo
25
25
  #
26
26
  # @since 2.0.0
27
27
  SPECIAL_FIELDS = {
28
- :sort => :$orderby,
29
- :hint => :$hint,
30
- :comment => :$comment,
31
- :snapshot => :$snapshot,
32
- :max_scan => :$maxScan,
33
- :max_value => :$max,
34
- :min_value => :$min,
35
- :max_time_ms => :$maxTimeMS,
36
- :return_key => :$returnKey,
37
- :show_disk_loc => :$showDiskLoc,
38
- :explain => :$explain
28
+ :sort => :$orderby,
29
+ :hint => :$hint,
30
+ :comment => :$comment,
31
+ :snapshot => :$snapshot,
32
+ :max_scan => :$maxScan,
33
+ :max_value => :$max,
34
+ :min_value => :$min,
35
+ :max_time_ms => :$maxTimeMS,
36
+ :return_key => :$returnKey,
37
+ :show_disk_loc => :$showDiskLoc,
38
+ :explain => :$explain
39
39
  }.freeze
40
40
 
41
41
  # Options to cursor flags mapping.
@@ -92,7 +92,7 @@ module Mongo
92
92
  #
93
93
  # @since 2.0.0
94
94
  def batch_size(batch_size = nil)
95
- configure(__method__, batch_size)
95
+ configure(:batch_size, batch_size)
96
96
  end
97
97
 
98
98
  # Associate a comment with the query.
@@ -110,7 +110,7 @@ module Mongo
110
110
  #
111
111
  # @since 2.0.0
112
112
  def comment(comment = nil)
113
- configure_modifier(__method__, comment)
113
+ configure_modifier(:comment, comment)
114
114
  end
115
115
 
116
116
  # Get a count of matching documents in the collection.
@@ -137,7 +137,9 @@ module Mongo
137
137
  cmd[:hint] = options[:hint] if options[:hint]
138
138
  cmd[:limit] = options[:limit] if options[:limit]
139
139
  cmd[:maxTimeMS] = options[:max_time_ms] if options[:max_time_ms]
140
- database.command(cmd, options).n
140
+ read_with_retry do
141
+ database.command(cmd, options).n
142
+ end
141
143
  end
142
144
 
143
145
  # Get a list of distinct values for a specific field.
@@ -160,7 +162,9 @@ module Mongo
160
162
  :key => field_name.to_s,
161
163
  :query => selector }
162
164
  cmd[:maxTimeMS] = options[:max_time_ms] if options[:max_time_ms]
163
- database.command(cmd, options).first['values']
165
+ read_with_retry do
166
+ database.command(cmd, options).first['values']
167
+ end
164
168
  end
165
169
 
166
170
  # The index that MongoDB will be forced to use for the query.
@@ -174,7 +178,7 @@ module Mongo
174
178
  #
175
179
  # @since 2.0.0
176
180
  def hint(hint = nil)
177
- configure_modifier(__method__, hint)
181
+ configure_modifier(:hint, hint)
178
182
  end
179
183
 
180
184
  # The max number of docs to return from the query.
@@ -188,7 +192,7 @@ module Mongo
188
192
  #
189
193
  # @since 2.0.0
190
194
  def limit(limit = nil)
191
- configure(__method__, limit)
195
+ configure(:limit, limit)
192
196
  end
193
197
 
194
198
  # Execute a map/reduce operation on the collection view.
@@ -218,7 +222,7 @@ module Mongo
218
222
  #
219
223
  # @since 2.0.0
220
224
  def max_scan(value = nil)
221
- configure_modifier(__method__, value)
225
+ configure_modifier(:max_scan, value)
222
226
  end
223
227
 
224
228
  # Set the maximum value to search.
@@ -232,7 +236,7 @@ module Mongo
232
236
  #
233
237
  # @since 2.1.0
234
238
  def max_value(value = nil)
235
- configure_modifier(__method__, value)
239
+ configure_modifier(:max_value, value)
236
240
  end
237
241
 
238
242
  # Set the minimum value to search.
@@ -246,7 +250,7 @@ module Mongo
246
250
  #
247
251
  # @since 2.1.0
248
252
  def min_value(value = nil)
249
- configure_modifier(__method__, value)
253
+ configure_modifier(:min_value, value)
250
254
  end
251
255
 
252
256
  # The server normally times out idle cursors after an inactivity period
@@ -259,7 +263,7 @@ module Mongo
259
263
  #
260
264
  # @since 2.0.0
261
265
  def no_cursor_timeout
262
- configure_flag(__method__)
266
+ configure_flag(:no_cursor_timeout)
263
267
  end
264
268
 
265
269
  # The fields to include or exclude from each doc in the result set.
@@ -278,7 +282,7 @@ module Mongo
278
282
  # @since 2.0.0
279
283
  def projection(document = nil)
280
284
  validate_doc!(document) if document
281
- configure(__method__, document)
285
+ configure(:projection, document)
282
286
  end
283
287
 
284
288
  # The read preference to use for the query.
@@ -294,7 +298,8 @@ module Mongo
294
298
  # @since 2.0.0
295
299
  def read(value = nil)
296
300
  return default_read if value.nil?
297
- configure(__method__, value.is_a?(Hash) ? ServerSelector.get(value) : value)
301
+ selector = value.is_a?(Hash) ? ServerSelector.get(client.options.merge(value)) : value
302
+ configure(:read, selector)
298
303
  end
299
304
 
300
305
  # Set whether to return only the indexed field or fields.
@@ -308,7 +313,7 @@ module Mongo
308
313
  #
309
314
  # @since 2.1.0
310
315
  def return_key(value = nil)
311
- configure_modifier(__method__, value)
316
+ configure_modifier(:return_key, value)
312
317
  end
313
318
 
314
319
  # Set whether the disk location should be shown for each document.
@@ -323,7 +328,7 @@ module Mongo
323
328
  #
324
329
  # @since 2.0.0
325
330
  def show_disk_loc(value = nil)
326
- configure_modifier(__method__, value)
331
+ configure_modifier(:show_disk_loc, value)
327
332
  end
328
333
 
329
334
  # The number of docs to skip before returning results.
@@ -338,7 +343,7 @@ module Mongo
338
343
  #
339
344
  # @since 2.0.0
340
345
  def skip(number = nil)
341
- configure(__method__, number)
346
+ configure(:skip, number)
342
347
  end
343
348
 
344
349
  # Set the snapshot value for the view.
@@ -353,7 +358,7 @@ module Mongo
353
358
  #
354
359
  # @since 2.0.0
355
360
  def snapshot(value = nil)
356
- configure_modifier(__method__, value)
361
+ configure_modifier(:snapshot, value)
357
362
  end
358
363
 
359
364
  # The key and direction pairs by which the result set will be sorted.
@@ -368,7 +373,7 @@ module Mongo
368
373
  #
369
374
  # @since 2.0.0
370
375
  def sort(spec = nil)
371
- configure_modifier(__method__, spec)
376
+ configure_modifier(:sort, spec)
372
377
  end
373
378
 
374
379
  # “meta” operators that let you modify the output or behavior of a query.
@@ -383,7 +388,7 @@ module Mongo
383
388
  # @since 2.1.0
384
389
  def modifiers(doc = nil)
385
390
  return @modifiers if doc.nil?
386
- new(options.merge(__method__ => doc))
391
+ new(options.merge(:modifiers => doc))
387
392
  end
388
393
 
389
394
  # A cumulative time limit in milliseconds for processing operations on a cursor.
@@ -397,7 +402,7 @@ module Mongo
397
402
  #
398
403
  # @since 2.1.0
399
404
  def max_time_ms(max = nil)
400
- configure_modifier(__method__, max)
405
+ configure_modifier(:max_time_ms, max)
401
406
  end
402
407
 
403
408
  private
@@ -35,7 +35,9 @@ module Mongo
35
35
  cmd[:fields] = projection if projection
36
36
  cmd[:sort] = sort if sort
37
37
  cmd[:maxTimeMS] = max_time_ms if max_time_ms
38
- database.command(cmd).first['value']
38
+ write_with_retry do
39
+ database.command(cmd).first['value']
40
+ end
39
41
  end
40
42
 
41
43
  # Finds a single document and replaces it.
@@ -81,8 +83,10 @@ module Mongo
81
83
  cmd[:new] = !!(opts[:return_document] && opts[:return_document] == :after)
82
84
  cmd[:upsert] = opts[:upsert] if opts[:upsert]
83
85
  cmd[:maxTimeMS] = max_time_ms if max_time_ms
84
- value = database.command(cmd).first['value']
85
- value unless value.nil? || value.empty?
86
+ write_with_retry do
87
+ value = database.command(cmd).first['value']
88
+ value unless value.nil? || value.empty?
89
+ end
86
90
  end
87
91
 
88
92
  # Remove documents from the collection.
@@ -166,24 +170,28 @@ module Mongo
166
170
  private
167
171
 
168
172
  def remove(value)
169
- Operation::Write::Delete.new(
170
- :delete => { q: selector, limit: value },
171
- :db_name => collection.database.name,
172
- :coll_name => collection.name,
173
- :write_concern => collection.write_concern
174
- ).execute(next_primary.context)
173
+ write_with_retry do
174
+ Operation::Write::Delete.new(
175
+ :delete => { Operation::Q => selector, Operation::LIMIT => value },
176
+ :db_name => collection.database.name,
177
+ :coll_name => collection.name,
178
+ :write_concern => collection.write_concern
179
+ ).execute(next_primary.context)
180
+ end
175
181
  end
176
182
 
177
183
  def update(spec, multi, opts)
178
- Operation::Write::Update.new(
179
- :update => { q: selector,
180
- u: spec,
181
- multi: multi,
182
- upsert: !!opts[:upsert] },
183
- :db_name => collection.database.name,
184
- :coll_name => collection.name,
185
- :write_concern => collection.write_concern
186
- ).execute(next_primary.context)
184
+ write_with_retry do
185
+ Operation::Write::Update.new(
186
+ :update => { Operation::Q => selector,
187
+ Operation::U => spec,
188
+ Operation::MULTI => multi,
189
+ Operation::UPSERT => !!opts[:upsert] },
190
+ :db_name => collection.database.name,
191
+ :coll_name => collection.name,
192
+ :write_concern => collection.write_concern
193
+ ).execute(next_primary.context)
194
+ end
187
195
  end
188
196
  end
189
197
  end
@@ -36,7 +36,17 @@ module Mongo
36
36
  # The default database options.
37
37
  #
38
38
  # @since 2.0.0
39
- DEFAULT_OPTIONS = { :database => ADMIN }.freeze
39
+ DEFAULT_OPTIONS = Options::Redacted.new(:database => ADMIN).freeze
40
+
41
+ # Database name field constant.
42
+ #
43
+ # @since 2.1.0
44
+ NAME = 'name'.freeze
45
+
46
+ # Databases constant.
47
+ #
48
+ # @since 2.1.0
49
+ DATABASES = 'databases'.freeze
40
50
 
41
51
  # The name of the collection that holds all the collection names.
42
52
  #
@@ -138,7 +148,7 @@ module Mongo
138
148
  #
139
149
  # @return [ Hash ] The result of the command execution.
140
150
  def command(operation, opts = {})
141
- preference = opts[:read] ? ServerSelector.get(opts[:read].merge(options)) : read_preference
151
+ preference = opts[:read] ? ServerSelector.get(client.options.merge(opts[:read])) : read_preference
142
152
  server = preference.select_server(cluster)
143
153
  Operation::Command.new({
144
154
  :selector => operation,
@@ -51,9 +51,10 @@ module Mongo
51
51
  def collection_names(options = {})
52
52
  @batch_size = options[:batch_size]
53
53
  server = next_primary
54
+ @limit = -1 if server.features.list_collections_enabled?
54
55
  collections_info(server).collect do |info|
55
- server.context.features.list_collections_enabled? ?
56
- info['name'] : info['name'].sub("#{@database.name}.", '')
56
+ server.features.list_collections_enabled? ?
57
+ info[Database::NAME] : info[Database::NAME].sub("#{@database.name}.", '')
57
58
  end
58
59
  end
59
60
 
@@ -80,7 +81,7 @@ module Mongo
80
81
  def initialize(database)
81
82
  @database = database
82
83
  @batch_size = nil
83
- @limit = -1
84
+ @limit = nil
84
85
  @collection = @database[Database::COMMAND]
85
86
  end
86
87
 
@@ -53,8 +53,8 @@ module Mongo
53
53
  #
54
54
  # @since 2.1.0
55
55
  def as_json(*args)
56
- document = { '$ref' => collection, '$id' => id }
57
- document.merge!('$db' => database) if database
56
+ document = { COLLECTION => collection, ID => id }
57
+ document.merge!(DATABASE => database) if database
58
58
  document
59
59
  end
60
60
 
@@ -101,8 +101,8 @@ module Mongo
101
101
  # @since 2.0.0
102
102
  def from_bson(bson)
103
103
  decoded = super
104
- if ref = decoded['$ref']
105
- decoded = DBRef.new(ref, decoded['$id'], decoded['$db'])
104
+ if ref = decoded[COLLECTION]
105
+ decoded = DBRef.new(ref, decoded[ID], decoded[DATABASE])
106
106
  end
107
107
  decoded
108
108
  end
@@ -19,6 +19,7 @@ module Mongo
19
19
  #
20
20
  # @since 2.0.0
21
21
  class FSBucket
22
+ extend Forwardable
22
23
 
23
24
  # The default root prefix.
24
25
  #
@@ -55,6 +56,12 @@ module Mongo
55
56
  # @since 2.1.0
56
57
  attr_reader :options
57
58
 
59
+ # Get client from the database.
60
+ #
61
+ # @since 2.1.0
62
+ def_delegators :database,
63
+ :client
64
+
58
65
  # Find files collection documents matching a given selector.
59
66
  #
60
67
  # @example Find files collection documents by a filename.
@@ -395,7 +402,7 @@ module Mongo
395
402
  # @since 2.1.0
396
403
  def read_preference
397
404
  @read_preference ||= @options[:read] ?
398
- ServerSelector.get((@options[:read] || {}).merge(database.options)) :
405
+ ServerSelector.get(Options::Redacted.new((@options[:read] || {}).merge(client.options))) :
399
406
  database.read_preference
400
407
  end
401
408
 
@@ -134,7 +134,7 @@ module Mongo
134
134
  # @since 2.1.0
135
135
  def read_preference
136
136
  @read_preference ||= @options[:read] ?
137
- ServerSelector.get((@options[:read] || {}).merge(fs.options)) :
137
+ ServerSelector.get(Options::Redacted.new((@options[:read] || {}).merge(fs.options))) :
138
138
  fs.read_preference
139
139
  end
140
140