mongo 2.5.0.beta → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (172) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/lib/mongo/address.rb +1 -1
  5. data/lib/mongo/address/unix.rb +1 -1
  6. data/lib/mongo/auth/user.rb +0 -5
  7. data/lib/mongo/auth/user/view.rb +4 -4
  8. data/lib/mongo/bulk_write.rb +60 -32
  9. data/lib/mongo/client.rb +44 -8
  10. data/lib/mongo/cluster.rb +14 -12
  11. data/lib/mongo/cluster/periodic_executor.rb +106 -0
  12. data/lib/mongo/cluster/{cursor_reaper.rb → reapers/cursor_reaper.rb} +5 -37
  13. data/lib/mongo/cluster/reapers/socket_reaper.rb +59 -0
  14. data/lib/mongo/collection.rb +9 -6
  15. data/lib/mongo/collection/view.rb +2 -2
  16. data/lib/mongo/collection/view/builder/aggregation.rb +2 -1
  17. data/lib/mongo/collection/view/builder/find_command.rb +1 -1
  18. data/lib/mongo/collection/view/change_stream.rb +14 -1
  19. data/lib/mongo/collection/view/map_reduce.rb +30 -13
  20. data/lib/mongo/collection/view/readable.rb +5 -5
  21. data/lib/mongo/collection/view/writable.rb +98 -51
  22. data/lib/mongo/error.rb +3 -0
  23. data/lib/mongo/error/invalid_txt_record.rb +27 -0
  24. data/lib/mongo/error/invalid_uri.rb +7 -6
  25. data/lib/mongo/error/mismatched_domain.rb +27 -0
  26. data/lib/mongo/error/no_srv_records.rb +26 -0
  27. data/lib/mongo/error/unsupported_features.rb +0 -18
  28. data/lib/mongo/index/view.rb +2 -2
  29. data/lib/mongo/operation.rb +1 -0
  30. data/lib/mongo/operation/causally_consistent.rb +33 -0
  31. data/lib/mongo/operation/commands.rb +2 -1
  32. data/lib/mongo/operation/commands/aggregate.rb +2 -7
  33. data/lib/mongo/operation/commands/count.rb +27 -0
  34. data/lib/mongo/operation/commands/distinct.rb +27 -0
  35. data/lib/mongo/operation/commands/find.rb +3 -1
  36. data/lib/mongo/operation/commands/map_reduce.rb +1 -0
  37. data/lib/mongo/operation/commands/parallel_scan.rb +1 -0
  38. data/lib/mongo/operation/specifiable.rb +12 -0
  39. data/lib/mongo/operation/uses_command_op_msg.rb +36 -5
  40. data/lib/mongo/operation/write.rb +0 -5
  41. data/lib/mongo/operation/write/bulk/bulkable.rb +4 -8
  42. data/lib/mongo/operation/write/bulk/mergable.rb +2 -0
  43. data/lib/mongo/operation/write/command/create_index.rb +19 -0
  44. data/lib/mongo/operation/write/command/create_user.rb +19 -0
  45. data/lib/mongo/operation/write/command/delete.rb +1 -2
  46. data/lib/mongo/operation/write/command/drop_index.rb +19 -0
  47. data/lib/mongo/operation/write/command/insert.rb +1 -2
  48. data/lib/mongo/operation/write/command/remove_user.rb +19 -0
  49. data/lib/mongo/operation/write/command/update.rb +1 -2
  50. data/lib/mongo/operation/write/command/update_user.rb +19 -0
  51. data/lib/mongo/operation/write/write_command_enabled.rb +1 -3
  52. data/lib/mongo/protocol/compressed.rb +2 -1
  53. data/lib/mongo/protocol/serializers.rb +6 -6
  54. data/lib/mongo/retryable.rb +48 -5
  55. data/lib/mongo/server.rb +15 -0
  56. data/lib/mongo/server/connection.rb +21 -1
  57. data/lib/mongo/server/connection_pool.rb +3 -0
  58. data/lib/mongo/server/connection_pool/queue.rb +50 -5
  59. data/lib/mongo/server/description.rb +11 -3
  60. data/lib/mongo/server/description/features.rb +26 -7
  61. data/lib/mongo/session.rb +133 -6
  62. data/lib/mongo/session/server_session.rb +30 -0
  63. data/lib/mongo/session/session_pool.rb +20 -20
  64. data/lib/mongo/uri.rb +88 -44
  65. data/lib/mongo/uri/srv_protocol.rb +158 -0
  66. data/lib/mongo/version.rb +1 -1
  67. data/lib/mongo/write_concern/normalizable.rb +12 -0
  68. data/mongo.gemspec +1 -2
  69. data/spec/mongo/address_spec.rb +12 -0
  70. data/spec/mongo/auth/user/view_spec.rb +1 -5
  71. data/spec/mongo/bulk_write_spec.rb +232 -401
  72. data/spec/mongo/change_stream_examples_spec.rb +150 -0
  73. data/spec/mongo/client_spec.rb +142 -2
  74. data/spec/mongo/cluster/cursor_reaper_spec.rb +0 -70
  75. data/spec/mongo/cluster/socket_reaper_spec.rb +32 -0
  76. data/spec/mongo/cluster_spec.rb +11 -7
  77. data/spec/mongo/collection/view/aggregation_spec.rb +46 -1
  78. data/spec/mongo/collection/view/builder/find_command_spec.rb +15 -0
  79. data/spec/mongo/collection/view/change_stream_spec.rb +79 -12
  80. data/spec/mongo/collection/view/map_reduce_spec.rb +120 -4
  81. data/spec/mongo/collection/view/readable_spec.rb +23 -5
  82. data/spec/mongo/collection_spec.rb +292 -102
  83. data/spec/mongo/command_monitoring_spec.rb +26 -32
  84. data/spec/mongo/crud_spec.rb +1 -1
  85. data/spec/mongo/cursor_spec.rb +2 -3
  86. data/spec/mongo/database_spec.rb +30 -14
  87. data/spec/mongo/dns_seedlist_discovery_spec.rb +94 -0
  88. data/spec/mongo/grid/fs_bucket_spec.rb +1 -1
  89. data/spec/mongo/grid/stream/write_spec.rb +1 -1
  90. data/spec/mongo/index/view_spec.rb +8 -46
  91. data/spec/mongo/operation/write/bulk/delete_spec.rb +2 -2
  92. data/spec/mongo/operation/write/bulk/insert_spec.rb +2 -10
  93. data/spec/mongo/operation/write/{create_index_spec.rb → command/create_index_spec.rb} +2 -6
  94. data/spec/mongo/operation/write/command/delete_spec.rb +35 -7
  95. data/spec/mongo/operation/write/{drop_index_spec.rb → command/drop_index_spec.rb} +1 -1
  96. data/spec/mongo/operation/write/command/insert_spec.rb +37 -6
  97. data/spec/mongo/operation/write/{remove_user_spec.rb → command/remove_user_spec.rb} +2 -6
  98. data/spec/mongo/operation/write/command/update_spec.rb +34 -7
  99. data/spec/mongo/operation/write/{update_user_spec.rb → command/update_user_spec.rb} +1 -1
  100. data/spec/mongo/operation/write/create_user_spec.rb +1 -1
  101. data/spec/mongo/operation/write/delete_spec.rb +1 -1
  102. data/spec/mongo/operation/write/insert_spec.rb +2 -10
  103. data/spec/mongo/operation/write/update_spec.rb +3 -15
  104. data/spec/mongo/retryable_spec.rb +1 -1
  105. data/spec/mongo/retryable_writes_spec.rb +815 -0
  106. data/spec/mongo/server/connection_pool/queue_spec.rb +35 -2
  107. data/spec/mongo/server/connection_pool_spec.rb +234 -1
  108. data/spec/mongo/server/connection_spec.rb +10 -6
  109. data/spec/mongo/server/description/features_spec.rb +51 -37
  110. data/spec/mongo/server/description_spec.rb +6 -3
  111. data/spec/mongo/server_spec.rb +87 -0
  112. data/spec/mongo/session/server_session_spec.rb +43 -0
  113. data/spec/mongo/session/session_pool_spec.rb +63 -27
  114. data/spec/mongo/session_spec.rb +247 -0
  115. data/spec/mongo/shell_examples_spec.rb +2 -2
  116. data/spec/mongo/uri/srv_protocol_spec.rb +933 -0
  117. data/spec/mongo/uri_spec.rb +42 -3
  118. data/spec/mongo/write_concern/acknowledged_spec.rb +11 -0
  119. data/spec/mongo/write_concern/unacknowledged_spec.rb +11 -0
  120. data/spec/spec_helper.rb +11 -25
  121. data/spec/support/authorization.rb +2 -1
  122. data/spec/support/connection_string.rb +8 -4
  123. data/spec/support/crud.rb +38 -24
  124. data/spec/support/crud/write.rb +30 -3
  125. data/spec/support/crud_tests/read/aggregate-out.yml +21 -0
  126. data/spec/support/crud_tests/write/bulkWrite-arrayFilters.yml +44 -0
  127. data/spec/support/crud_tests/write/findOneAndUpdate-arrayFilters.yml +1 -1
  128. data/spec/support/crud_tests/write/insertMany.yml +1 -3
  129. data/spec/support/crud_tests/write/replaceOne.yml +1 -1
  130. data/spec/support/crud_tests/write/updateMany-arrayFilters.yml +1 -1
  131. data/spec/support/crud_tests/write/updateOne-arrayFilters.yml +1 -1
  132. data/spec/support/dns_seedlist_discovery_tests/longer-parent-in-return.yml +11 -0
  133. data/spec/support/dns_seedlist_discovery_tests/misformatted-option.yml +5 -0
  134. data/spec/support/dns_seedlist_discovery_tests/no-results.yml +5 -0
  135. data/spec/support/dns_seedlist_discovery_tests/not-enough-parts.yml +5 -0
  136. data/spec/support/dns_seedlist_discovery_tests/one-result-default-port.yml +10 -0
  137. data/spec/support/dns_seedlist_discovery_tests/one-txt-record-multiple-strings.yml +10 -0
  138. data/spec/support/dns_seedlist_discovery_tests/one-txt-record.yml +11 -0
  139. data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch1.yml +5 -0
  140. data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch2.yml +5 -0
  141. data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch3.yml +5 -0
  142. data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch4.yml +5 -0
  143. data/spec/support/dns_seedlist_discovery_tests/parent-part-mismatch5.yml +5 -0
  144. data/spec/support/dns_seedlist_discovery_tests/returned-parent-too-short.yml +5 -0
  145. data/spec/support/dns_seedlist_discovery_tests/returned-parent-wrong.yml +5 -0
  146. data/spec/support/dns_seedlist_discovery_tests/two-results-default-port.yml +11 -0
  147. data/spec/support/dns_seedlist_discovery_tests/two-results-nonstandard-port.yml +11 -0
  148. data/spec/support/dns_seedlist_discovery_tests/two-txt-records.yml +5 -0
  149. data/spec/support/dns_seedlist_discovery_tests/txt-record-not-allowed-option.yml +5 -0
  150. data/spec/support/dns_seedlist_discovery_tests/txt-record-with-overridden-ssl-option.yml +11 -0
  151. data/spec/support/dns_seedlist_discovery_tests/txt-record-with-overridden-uri-option.yml +11 -0
  152. data/spec/support/dns_seedlist_discovery_tests/txt-record-with-unallowed-option.yml +5 -0
  153. data/spec/support/dns_seedlist_discovery_tests/uri-with-port.yml +5 -0
  154. data/spec/support/dns_seedlist_discovery_tests/uri-with-two-hosts.yml +5 -0
  155. data/spec/support/retryable_writes_tests/bulkWrite.yml +305 -0
  156. data/spec/support/retryable_writes_tests/deleteOne.yml +51 -0
  157. data/spec/support/retryable_writes_tests/findOneAndDelete.yml +52 -0
  158. data/spec/support/retryable_writes_tests/findOneAndReplace.yml +57 -0
  159. data/spec/support/retryable_writes_tests/findOneAndUpdate.yml +56 -0
  160. data/spec/support/retryable_writes_tests/insertMany.yml +72 -0
  161. data/spec/support/retryable_writes_tests/insertOne.yml +55 -0
  162. data/spec/support/retryable_writes_tests/replaceOne.yml +60 -0
  163. data/spec/support/retryable_writes_tests/updateOne.yml +120 -0
  164. data/spec/support/shared/session.rb +525 -24
  165. metadata +437 -350
  166. metadata.gz.sig +0 -0
  167. data/lib/mongo/operation/commands/user_query.rb +0 -72
  168. data/lib/mongo/operation/write/create_index.rb +0 -67
  169. data/lib/mongo/operation/write/create_user.rb +0 -50
  170. data/lib/mongo/operation/write/drop_index.rb +0 -63
  171. data/lib/mongo/operation/write/remove_user.rb +0 -48
  172. data/lib/mongo/operation/write/update_user.rb +0 -50
@@ -15,11 +15,14 @@
15
15
  require 'set'
16
16
 
17
17
  module Mongo
18
+
18
19
  class Cluster
19
20
 
20
21
  # A manager that sends kill cursors operations at regular intervals to close
21
22
  # cursors that have been garbage collected without being exhausted.
22
23
  #
24
+ # @api private
25
+ #
23
26
  # @since 2.3.0
24
27
  class CursorReaper
25
28
  include Retryable
@@ -41,22 +44,8 @@ module Mongo
41
44
  @to_kill = {}
42
45
  @active_cursors = Set.new
43
46
  @mutex = Mutex.new
44
- @thread = nil
45
47
  end
46
48
 
47
- # Start the cursor reaper's thread.
48
- #
49
- # @example Start the cursor reaper's thread.
50
- # reaper.run!
51
- #
52
- # @api private
53
- #
54
- # @since 2.3.0
55
- def run!
56
- @thread && @thread.alive? ? @thread : start!
57
- end
58
- alias :restart! :run!
59
-
60
49
  # Schedule a kill cursors operation to be eventually executed.
61
50
  #
62
51
  # @example Schedule a kill cursors operation.
@@ -112,18 +101,6 @@ module Mongo
112
101
  end
113
102
  end
114
103
 
115
- # Stop the cursor reaper's thread.
116
- #
117
- # @example Stop the cursor reaper's thread.
118
- # reaper.stop!
119
- #
120
- # @api private
121
- #
122
- # @since 2.3.0
123
- def stop!
124
- @thread.kill && @thread.stop?
125
- end
126
-
127
104
  # Execute all pending kill cursors operations.
128
105
  #
129
106
  # @example Execute pending kill cursors operations.
@@ -158,17 +135,8 @@ module Mongo
158
135
  end
159
136
  end
160
137
  end
161
-
162
- private
163
-
164
- def start!
165
- @thread = Thread.new(FREQUENCY) do |i|
166
- loop do
167
- sleep(i)
168
- kill_cursors
169
- end
170
- end
171
- end
138
+ alias :execute :kill_cursors
139
+ alias :flush :kill_cursors
172
140
  end
173
141
  end
174
142
  end
@@ -0,0 +1,59 @@
1
+ # Copyright (C) 2014-2017 MongoDB, Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+
17
+ class Cluster
18
+
19
+ # A manager that calls a method on each of a cluster's pools to close stale
20
+ # sockets.
21
+ #
22
+ # @api private
23
+ #
24
+ # @since 2.5.0
25
+ class SocketReaper
26
+
27
+ # Initialize the SocketReaper object.
28
+ #
29
+ # @example Initialize the socket reaper.
30
+ # SocketReaper.new(cluster)
31
+ #
32
+ # @params [ Mongo::Cluster ] cluster The cluster whose pools' stale sockets
33
+ # need to be reaped at regular intervals.
34
+ #
35
+ # @since 2.5.0
36
+ def initialize(cluster)
37
+ @cluster = cluster
38
+ end
39
+
40
+ # Execute the operation to close the pool's stale sockets.
41
+ #
42
+ # @example Close the stale sockets in each of the cluster's pools.
43
+ # socket_reaper.execute
44
+ #
45
+ # @since 2.5.0
46
+ def execute
47
+ @cluster.servers.each do |server|
48
+ server.pool.close_stale_sockets!
49
+ end and true
50
+ end
51
+
52
+ # When the socket reaper is garbage-collected, there's no need to close stale sockets;
53
+ # sockets will be closed anyway when the pools are garbage-collected.
54
+ #
55
+ # @since 2.5.0
56
+ def flush; end
57
+ end
58
+ end
59
+ end
@@ -174,7 +174,7 @@ module Mongo
174
174
  # @example Force the collection to be created.
175
175
  # collection.create
176
176
  #
177
- # @param [ Hash ] options The options for the create operation.
177
+ # @param [ Hash ] opts The options for the create operation.
178
178
  #
179
179
  # @option options [ Session ] :session The session to use for the operation.
180
180
  #
@@ -206,7 +206,7 @@ module Mongo
206
206
  # @example Drop the collection.
207
207
  # collection.drop
208
208
  #
209
- # @param [ Hash ] options The options for the drop operation.
209
+ # @param [ Hash ] opts The options for the drop operation.
210
210
  #
211
211
  # @option options [ Session ] :session The session to use for the operation.
212
212
  #
@@ -283,10 +283,12 @@ module Mongo
283
283
  # @option options [ Integer ] :max_time_ms The maximum amount of time in milliseconds to allow the
284
284
  # aggregation to run.
285
285
  # @option options [ true, false ] :use_cursor Indicates whether the command will request that the server
286
- # provide results using a cursor.
286
+ # provide results using a cursor. Note that as of server version 3.6, aggregations always provide results
287
+ # using a cursor and this option is therefore not valid.
287
288
  # @option options [ true, false ] :bypass_document_validation Whether or
288
289
  # not to skip document level validation.
289
290
  # @option options [ Hash ] :collation The collation to use.
291
+ # @option options [ String ] :comment Associate a comment with the aggregation.
290
292
  # @option options [ Session ] :session The session to use.
291
293
  #
292
294
  # @return [ Aggregation ] The aggregation object.
@@ -417,7 +419,7 @@ module Mongo
417
419
  # @since 2.0.0
418
420
  def insert_one(document, options = {})
419
421
  client.send(:with_session, options) do |session|
420
- write_with_retry(session, Proc.new { next_primary }) do |server|
422
+ write_with_retry(session, write_concern) do |server, txn_num|
421
423
  Operation::Write::Insert.new(
422
424
  :documents => [ document ],
423
425
  :db_name => database.name,
@@ -426,8 +428,9 @@ module Mongo
426
428
  :bypass_document_validation => !!options[:bypass_document_validation],
427
429
  :options => options,
428
430
  :id_generator => client.options[:id_generator],
429
- :session => session
430
- ).execute(server)
431
+ :session => session,
432
+ :txn_num => txn_num
433
+ ).execute(server)
431
434
  end
432
435
  end
433
436
  end
@@ -199,8 +199,8 @@ module Mongo
199
199
 
200
200
  def view; self; end
201
201
 
202
- def with_session
203
- client.send(:with_session, @options) do |session|
202
+ def with_session(opts = {})
203
+ client.send(:with_session, @options.merge(opts)) do |session|
204
204
  yield(session)
205
205
  end
206
206
  end
@@ -35,7 +35,8 @@ module Mongo
35
35
  :explain => 'explain',
36
36
  :bypass_document_validation => 'bypassDocumentValidation',
37
37
  :collation => 'collation',
38
- :hint => 'hint'
38
+ :hint => 'hint',
39
+ :comment => 'comment'
39
40
  ).freeze
40
41
 
41
42
  def_delegators :@view, :collection, :database, :read, :write_concern
@@ -63,7 +63,7 @@ module Mongo
63
63
  #
64
64
  # @since 2.2.0
65
65
  def explain_specification
66
- { selector: { explain: find_command }, db_name: database.name, read: read }
66
+ { selector: { explain: find_command }, db_name: database.name, read: read, session: @session }
67
67
  end
68
68
 
69
69
  # Create the find command builder.
@@ -51,7 +51,7 @@ module Mongo
51
51
  #
52
52
  # @param [ Collection::View ] view The collection view.
53
53
  # @param [ Array<Hash> ] pipeline The pipeline of operators to filter the change notifications.
54
- # @param [ Hash ] opts The change stream options.
54
+ # @param [ Hash ] options The change stream options.
55
55
  #
56
56
  # @option options [ String ] :full_document Allowed values: ‘default’, ‘updateLookup’. Defaults to ‘default’.
57
57
  # When set to ‘updateLookup’, the change notification for partial updates will include both a delta
@@ -130,6 +130,19 @@ module Mongo
130
130
  @cursor.nil?
131
131
  end
132
132
 
133
+ # Get a formatted string for use in inspection.
134
+ #
135
+ # @example Inspect the change stream object.
136
+ # stream.inspect
137
+ #
138
+ # @return [ String ] The change stream inspection.
139
+ #
140
+ # @since 2.5.0
141
+ def inspect
142
+ "#<Mongo::Collection::View:ChangeStream:0x#{object_id} filters=#{@change_stream_filters} " +
143
+ "options=#{@options} resume_token=#{@resume_token}>"
144
+ end
145
+
133
146
  private
134
147
 
135
148
  def cache_resume_token(doc)
@@ -41,10 +41,10 @@ module Mongo
41
41
  attr_reader :view
42
42
 
43
43
  # @return [ String ] map The map function.
44
- attr_reader :map
44
+ attr_reader :map_function
45
45
 
46
46
  # @return [ String ] reduce The reduce function.
47
- attr_reader :reduce
47
+ attr_reader :reduce_function
48
48
 
49
49
  # Delegate necessary operations to the view.
50
50
  def_delegators :view, :collection, :read, :cluster
@@ -66,9 +66,10 @@ module Mongo
66
66
  # @yieldparam [ Hash ] Each matching document.
67
67
  def each
68
68
  @cursor = nil
69
- session = client.send(:get_session, view.options)
70
- write_with_retry(session, Proc.new { server_selector.select_server(cluster, false) }) do |server|
69
+ session = client.send(:get_session, @options)
70
+ legacy_write_with_retry do |server|
71
71
  result = send_initial_query(server, session)
72
+ result = send_fetch_query(server, session) unless inline?
72
73
  @cursor = Cursor.new(view, result, server, session: session)
73
74
  end
74
75
  @cursor.each do |doc|
@@ -105,8 +106,8 @@ module Mongo
105
106
  # @since 2.0.0
106
107
  def initialize(view, map, reduce, options = {})
107
108
  @view = view
108
- @map = map.freeze
109
- @reduce = reduce.freeze
109
+ @map_function = map.freeze
110
+ @reduce_function = reduce.freeze
110
111
  @options = BSON::Document.new(options).freeze
111
112
  end
112
113
 
@@ -180,6 +181,23 @@ module Mongo
180
181
  configure(:verbose, value)
181
182
  end
182
183
 
184
+ # Execute the map reduce, without doing a fetch query to retrieve the results
185
+ # if outputted to a collection.
186
+ #
187
+ # @example Execute the map reduce and get the raw result.
188
+ # map_reduce.execute
189
+ #
190
+ # @return [ Mongo::Operation::Result ] The raw map reduce result
191
+ #
192
+ # @since 2.5.0
193
+ def execute
194
+ view.send(:with_session, @options) do |session|
195
+ legacy_write_with_retry do |server|
196
+ send_initial_query(server, session)
197
+ end
198
+ end
199
+ end
200
+
183
201
  private
184
202
 
185
203
  def server_selector
@@ -190,12 +208,12 @@ module Mongo
190
208
  out.nil? || out == { inline: 1 } || out == { INLINE => 1 }
191
209
  end
192
210
 
193
- def map_reduce_spec(session)
194
- Builder::MapReduce.new(map, reduce, view, options.merge(session: session)).specification
211
+ def map_reduce_spec(session = nil)
212
+ Builder::MapReduce.new(map_function, reduce_function, view, options.merge(session: session)).specification
195
213
  end
196
214
 
197
215
  def new(options)
198
- MapReduce.new(view, map, reduce, options)
216
+ MapReduce.new(view, map_function, reduce_function, options)
199
217
  end
200
218
 
201
219
  def initial_query_op(session)
@@ -216,16 +234,15 @@ module Mongo
216
234
  server = cluster.next_primary(false)
217
235
  end
218
236
  validate_collation!(server)
219
- result = initial_query_op(session).execute(server)
220
- inline? ? result : send_fetch_query(server, session)
237
+ initial_query_op(session).execute(server)
221
238
  end
222
239
 
223
240
  def fetch_query_spec
224
- Builder::MapReduce.new(map, reduce, view, options).query_specification
241
+ Builder::MapReduce.new(map_function, reduce_function, view, options).query_specification
225
242
  end
226
243
 
227
244
  def find_command_spec(session)
228
- Builder::MapReduce.new(map, reduce, view, options.merge(session: session)).command_specification
245
+ Builder::MapReduce.new(map_function, reduce_function, view, options.merge(session: session)).command_specification
229
246
  end
230
247
 
231
248
  def fetch_query_op(server, session)
@@ -138,8 +138,8 @@ module Mongo
138
138
  read_with_retry do
139
139
  server = selector.select_server(cluster, false)
140
140
  apply_collation!(cmd, server, opts)
141
- with_session do |session|
142
- Operation::Commands::Command.new({
141
+ with_session(opts) do |session|
142
+ Operation::Commands::Count.new({
143
143
  :selector => cmd,
144
144
  :db_name => database.name,
145
145
  :options => {:limit => -1},
@@ -178,8 +178,8 @@ module Mongo
178
178
  read_with_retry do
179
179
  server = selector.select_server(cluster, false)
180
180
  apply_collation!(cmd, server, opts)
181
- with_session do |session|
182
- Operation::Commands::Command.new({
181
+ with_session(opts) do |session|
182
+ Operation::Commands::Distinct.new({
183
183
  :selector => cmd,
184
184
  :db_name => database.name,
185
185
  :options => {:limit => -1},
@@ -231,7 +231,7 @@ module Mongo
231
231
  #
232
232
  # @since 2.0.0
233
233
  def map_reduce(map, reduce, options = {})
234
- MapReduce.new(self, map, reduce, options)
234
+ MapReduce.new(self, map, reduce, @options.merge(options))
235
235
  end
236
236
 
237
237
  # Set the max number of documents to scan.
@@ -46,14 +46,15 @@ module Mongo
46
46
  cmd[:maxTimeMS] = max_time_ms if max_time_ms
47
47
  cmd[:writeConcern] = write_concern.options if write_concern
48
48
 
49
- with_session do |session|
50
- write_with_retry(session, Proc.new { next_primary }) do |server|
49
+ with_session(opts) do |session|
50
+ write_with_retry(session, write_concern) do |server, txn_num|
51
51
  apply_collation!(cmd, server, opts)
52
- Operation::Commands::Command.new({
53
- :selector => cmd,
54
- :db_name => database.name,
55
- :session => session
56
- }).execute(server)
52
+ Operation::Commands::Command.new(
53
+ :selector => cmd,
54
+ :db_name => database.name,
55
+ :session => session,
56
+ :txn_num => txn_num
57
+ ).execute(server)
57
58
  end
58
59
  end.first['value']
59
60
  end
@@ -99,7 +100,7 @@ module Mongo
99
100
  # @option opts [ Hash ] :write_concern The write concern options.
100
101
  # Defaults to the collection's write concern.
101
102
  # @option opts [ Hash ] :collation The collation to use.
102
- # @options opts [ Array ] :array_filters A set of filters specifying to which array elements
103
+ # @option opts [ Array ] :array_filters A set of filters specifying to which array elements
103
104
  # an update should apply.
104
105
  #
105
106
  # @return [ BSON::Document ] The document.
@@ -116,15 +117,16 @@ module Mongo
116
117
  cmd[:bypassDocumentValidation] = !!opts[:bypass_document_validation]
117
118
  cmd[:writeConcern] = write_concern.options if write_concern
118
119
 
119
- value = with_session do |session|
120
- write_with_retry(session, Proc.new { next_primary }) do |server|
120
+ value = with_session(opts) do |session|
121
+ write_with_retry(session, write_concern) do |server, txn_num|
121
122
  apply_collation!(cmd, server, opts)
122
123
  apply_array_filters!(cmd, server, opts)
123
124
  Operation::Commands::Command.new(
124
- :selector => cmd,
125
- :db_name => database.name,
126
- :session => session
127
- ).execute(server)
125
+ :selector => cmd,
126
+ :db_name => database.name,
127
+ :session => session,
128
+ :txn_num => txn_num
129
+ ).execute(server)
128
130
  end
129
131
  end.first['value']
130
132
  value unless value.nil? || value.empty?
@@ -143,7 +145,19 @@ module Mongo
143
145
  #
144
146
  # @since 2.0.0
145
147
  def delete_many(opts = {})
146
- remove(0, opts)
148
+ delete_doc = { Operation::Q => filter, Operation::LIMIT => 0 }
149
+ with_session(opts) do |session|
150
+ legacy_write_with_retry do |server|
151
+ apply_collation!(delete_doc, server, opts)
152
+ Operation::Write::Delete.new(
153
+ :delete => delete_doc,
154
+ :db_name => collection.database.name,
155
+ :coll_name => collection.name,
156
+ :write_concern => collection.write_concern,
157
+ :session => session
158
+ ).execute(server)
159
+ end
160
+ end
147
161
  end
148
162
 
149
163
  # Remove a document from the collection.
@@ -159,7 +173,21 @@ module Mongo
159
173
  #
160
174
  # @since 2.0.0
161
175
  def delete_one(opts = {})
162
- remove(1, opts)
176
+ delete_doc = { Operation::Q => filter, Operation::LIMIT => 1 }
177
+ write_concern = collection.write_concern
178
+ with_session(opts) do |session|
179
+ write_with_retry(session, write_concern) do |server, txn_num|
180
+ apply_collation!(delete_doc, server, opts)
181
+ Operation::Write::Delete.new(
182
+ :delete => delete_doc,
183
+ :db_name => collection.database.name,
184
+ :coll_name => collection.name,
185
+ :write_concern => write_concern,
186
+ :session => session,
187
+ :txn_num => txn_num
188
+ ).execute(server)
189
+ end
190
+ end
163
191
  end
164
192
 
165
193
  # Replaces a single document in the database with the new document.
@@ -178,7 +206,28 @@ module Mongo
178
206
  #
179
207
  # @since 2.0.0
180
208
  def replace_one(replacement, opts = {})
181
- update(replacement, false, opts)
209
+ update_doc = { Operation::Q => filter,
210
+ Operation::U => replacement,
211
+ Operation::MULTI => false,
212
+ Operation::UPSERT => !!opts[:upsert]
213
+ }
214
+ write_concern = collection.write_concern
215
+ with_session(opts) do |session|
216
+ write_with_retry(session, write_concern) do |server, txn_num|
217
+ apply_collation!(update_doc, server, opts)
218
+ apply_array_filters!(update_doc, server, opts)
219
+
220
+ Operation::Write::Update.new(
221
+ :update => update_doc,
222
+ :db_name => collection.database.name,
223
+ :coll_name => collection.name,
224
+ :write_concern => write_concern,
225
+ :bypass_document_validation => !!opts[:bypass_document_validation],
226
+ :session => session,
227
+ :txn_num => txn_num
228
+ ).execute(server)
229
+ end
230
+ end
182
231
  end
183
232
 
184
233
  # Update documents in the collection.
@@ -199,7 +248,24 @@ module Mongo
199
248
  #
200
249
  # @since 2.0.0
201
250
  def update_many(spec, opts = {})
202
- update(spec, true, opts)
251
+ update_doc = { Operation::Q => filter,
252
+ Operation::U => spec,
253
+ Operation::MULTI => true,
254
+ Operation::UPSERT => !!opts[:upsert] }
255
+ with_session(opts) do |session|
256
+ legacy_write_with_retry do |server|
257
+ apply_collation!(update_doc, server, opts)
258
+ apply_array_filters!(update_doc, server, opts)
259
+ Operation::Write::Update.new(
260
+ :update => update_doc,
261
+ :db_name => collection.database.name,
262
+ :coll_name => collection.name,
263
+ :write_concern => collection.write_concern,
264
+ :bypass_document_validation => !!opts[:bypass_document_validation],
265
+ :session => session
266
+ ).execute(server)
267
+ end
268
+ end
203
269
  end
204
270
 
205
271
  # Update a single document in the collection.
@@ -220,50 +286,31 @@ module Mongo
220
286
  #
221
287
  # @since 2.0.0
222
288
  def update_one(spec, opts = {})
223
- update(spec, false, opts)
224
- end
225
-
226
- private
227
-
228
- def remove(value, opts = {})
229
- delete_doc = { Operation::Q => filter, Operation::LIMIT => value }
230
-
231
- with_session do |session|
232
- write_with_retry(session, Proc.new { next_primary }) do |server|
233
- apply_collation!(delete_doc, server, opts)
234
- Operation::Write::Delete.new(
235
- :delete => delete_doc,
236
- :db_name => collection.database.name,
237
- :coll_name => collection.name,
238
- :write_concern => collection.write_concern,
239
- :session => session
240
- ).execute(server)
241
- end
242
- end
243
- end
244
-
245
- def update(spec, multi, opts)
246
289
  update_doc = { Operation::Q => filter,
247
290
  Operation::U => spec,
248
- Operation::MULTI => multi,
291
+ Operation::MULTI => false,
249
292
  Operation::UPSERT => !!opts[:upsert] }
250
-
251
- with_session do |session|
252
- write_with_retry(session, Proc.new { next_primary }) do |server|
293
+ write_concern = collection.write_concern
294
+ with_session(opts) do |session|
295
+ write_with_retry(session, write_concern) do |server, txn_num|
253
296
  apply_collation!(update_doc, server, opts)
254
297
  apply_array_filters!(update_doc, server, opts)
298
+
255
299
  Operation::Write::Update.new(
256
- :update => update_doc,
257
- :db_name => collection.database.name,
258
- :coll_name => collection.name,
259
- :write_concern => collection.write_concern,
260
- :bypass_document_validation => !!opts[:bypass_document_validation],
261
- :session => session
300
+ :update => update_doc,
301
+ :db_name => collection.database.name,
302
+ :coll_name => collection.name,
303
+ :write_concern => write_concern,
304
+ :bypass_document_validation => !!opts[:bypass_document_validation],
305
+ :session => session,
306
+ :txn_num => txn_num
262
307
  ).execute(server)
263
308
  end
264
309
  end
265
310
  end
266
311
 
312
+ private
313
+
267
314
  def apply_array_filters!(doc, server, opts = {})
268
315
  if filters = opts[:array_filters] || opts[ARRAY_FILTERS]
269
316
  validate_array_filters!(server, filters)