mongo 2.5.0.beta → 2.5.0

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 (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)