mongo 2.9.2 → 2.10.0.rc0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (227) 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.rb +1 -0
  5. data/lib/mongo/auth/user/view.rb +4 -4
  6. data/lib/mongo/bulk_write.rb +14 -8
  7. data/lib/mongo/bulk_write/result.rb +1 -1
  8. data/lib/mongo/bulk_write/result_combiner.rb +2 -2
  9. data/lib/mongo/bulk_write/transformable.rb +17 -9
  10. data/lib/mongo/client.rb +107 -16
  11. data/lib/mongo/cluster.rb +47 -25
  12. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +1 -1
  13. data/lib/mongo/cluster_time.rb +139 -0
  14. data/lib/mongo/collection.rb +84 -25
  15. data/lib/mongo/collection/view.rb +7 -3
  16. data/lib/mongo/collection/view/aggregation.rb +4 -4
  17. data/lib/mongo/collection/view/builder/aggregation.rb +31 -6
  18. data/lib/mongo/collection/view/builder/find_command.rb +4 -1
  19. data/lib/mongo/collection/view/builder/map_reduce.rb +4 -1
  20. data/lib/mongo/collection/view/change_stream.rb +54 -66
  21. data/lib/mongo/collection/view/iterable.rb +2 -2
  22. data/lib/mongo/collection/view/map_reduce.rb +6 -4
  23. data/lib/mongo/collection/view/readable.rb +36 -16
  24. data/lib/mongo/collection/view/writable.rb +68 -22
  25. data/lib/mongo/cursor.rb +87 -20
  26. data/lib/mongo/database.rb +47 -43
  27. data/lib/mongo/database/view.rb +54 -11
  28. data/lib/mongo/error.rb +13 -4
  29. data/lib/mongo/error/invalid_write_concern.rb +2 -2
  30. data/lib/mongo/error/operation_failure.rb +65 -11
  31. data/lib/mongo/error/parser.rb +41 -8
  32. data/lib/mongo/grid/fs_bucket.rb +26 -6
  33. data/lib/mongo/grid/stream/read.rb +9 -2
  34. data/lib/mongo/grid/stream/write.rb +21 -5
  35. data/lib/mongo/index/view.rb +3 -3
  36. data/lib/mongo/lint.rb +10 -3
  37. data/lib/mongo/operation.rb +2 -0
  38. data/lib/mongo/operation/aggregate/result.rb +19 -6
  39. data/lib/mongo/operation/collections_info.rb +1 -1
  40. data/lib/mongo/operation/get_more/result.rb +9 -0
  41. data/lib/mongo/operation/list_collections/command.rb +1 -3
  42. data/lib/mongo/operation/list_collections/op_msg.rb +1 -2
  43. data/lib/mongo/operation/parallel_scan/command.rb +4 -1
  44. data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -1
  45. data/lib/mongo/operation/result.rb +27 -4
  46. data/lib/mongo/operation/shared/executable.rb +19 -5
  47. data/lib/mongo/operation/shared/executable_no_validate.rb +1 -2
  48. data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -9
  49. data/lib/mongo/operation/shared/polymorphic_result.rb +9 -1
  50. data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
  51. data/lib/mongo/operation/shared/sessions_supported.rb +42 -32
  52. data/lib/mongo/operation/shared/specifiable.rb +40 -0
  53. data/lib/mongo/operation/shared/unpinnable.rb +39 -0
  54. data/lib/mongo/operation/shared/write.rb +1 -1
  55. data/lib/mongo/protocol/update.rb +6 -2
  56. data/lib/mongo/retryable.rb +79 -39
  57. data/lib/mongo/server/connection.rb +10 -3
  58. data/lib/mongo/server/description.rb +25 -1
  59. data/lib/mongo/server/monitor/connection.rb +1 -1
  60. data/lib/mongo/server_selector.rb +10 -0
  61. data/lib/mongo/server_selector/selectable.rb +172 -32
  62. data/lib/mongo/session.rb +654 -581
  63. data/lib/mongo/session/session_pool.rb +1 -1
  64. data/lib/mongo/socket.rb +7 -28
  65. data/lib/mongo/socket/ssl.rb +26 -1
  66. data/lib/mongo/socket/tcp.rb +3 -0
  67. data/lib/mongo/socket/unix.rb +3 -0
  68. data/lib/mongo/uri.rb +112 -265
  69. data/lib/mongo/uri/srv_protocol.rb +4 -1
  70. data/lib/mongo/version.rb +1 -1
  71. data/lib/mongo/write_concern.rb +10 -29
  72. data/lib/mongo/write_concern/acknowledged.rb +12 -0
  73. data/lib/mongo/write_concern/base.rb +17 -13
  74. data/lib/mongo/write_concern/unacknowledged.rb +12 -0
  75. data/spec/atlas/atlas_connectivity_spec.rb +7 -37
  76. data/spec/atlas/operations_spec.rb +25 -0
  77. data/spec/integration/change_stream_examples_spec.rb +45 -31
  78. data/spec/integration/change_stream_spec.rb +305 -5
  79. data/spec/integration/client_spec.rb +44 -0
  80. data/spec/integration/command_monitoring_spec.rb +1 -0
  81. data/spec/integration/command_spec.rb +7 -1
  82. data/spec/integration/mmapv1_spec.rb +28 -0
  83. data/spec/integration/mongos_pinning_spec.rb +34 -0
  84. data/spec/integration/operation_failure_code_spec.rb +2 -2
  85. data/spec/integration/{read_concern.rb → read_concern_spec.rb} +7 -1
  86. data/spec/integration/read_preference_spec.rb +485 -0
  87. data/spec/integration/retryable_writes_spec.rb +8 -19
  88. data/spec/integration/sdam_error_handling_spec.rb +1 -1
  89. data/spec/integration/sdam_events_spec.rb +2 -2
  90. data/spec/integration/server_description_spec.rb +14 -17
  91. data/spec/integration/server_selector_spec.rb +7 -3
  92. data/spec/integration/server_spec.rb +48 -0
  93. data/spec/integration/ssl_uri_options_spec.rb +1 -1
  94. data/spec/integration/step_down_spec.rb +10 -4
  95. data/spec/integration/transactions_examples_spec.rb +11 -10
  96. data/spec/lite_spec_helper.rb +19 -16
  97. data/spec/mongo/auth/scram/negotiation_spec.rb +11 -8
  98. data/spec/mongo/bulk_write/ordered_combiner_spec.rb +6 -6
  99. data/spec/mongo/bulk_write/unordered_combiner_spec.rb +4 -4
  100. data/spec/mongo/bulk_write_spec.rb +12 -2
  101. data/spec/mongo/client_construction_spec.rb +160 -8
  102. data/spec/mongo/client_spec.rb +5 -4
  103. data/spec/mongo/cluster_spec.rb +6 -6
  104. data/spec/mongo/cluster_time_spec.rb +148 -0
  105. data/spec/mongo/collection/view/aggregation_spec.rb +34 -15
  106. data/spec/mongo/collection/view/change_stream_spec.rb +62 -3
  107. data/spec/mongo/collection/view/map_reduce_spec.rb +7 -5
  108. data/spec/mongo/collection/view/readable_spec.rb +4 -4
  109. data/spec/mongo/collection_spec.rb +331 -14
  110. data/spec/mongo/cursor_spec.rb +117 -5
  111. data/spec/mongo/database_spec.rb +240 -8
  112. data/spec/mongo/error/operation_failure_spec.rb +47 -1
  113. data/spec/mongo/error/parser_spec.rb +160 -23
  114. data/spec/mongo/operation/insert/bulk_spec.rb +2 -1
  115. data/spec/mongo/operation/result_spec.rb +27 -0
  116. data/spec/mongo/operation/update/bulk_spec.rb +1 -0
  117. data/spec/mongo/retryable_spec.rb +2 -0
  118. data/spec/mongo/server/app_metadata_spec.rb +2 -2
  119. data/spec/mongo/server/connection_spec.rb +13 -17
  120. data/spec/mongo/server/monitor/connection_spec.rb +13 -10
  121. data/spec/mongo/server_selector_spec.rb +34 -2
  122. data/spec/mongo/session/session_pool_spec.rb +14 -3
  123. data/spec/mongo/session_spec.rb +3 -3
  124. data/spec/mongo/session_transaction_spec.rb +4 -3
  125. data/spec/mongo/socket/ssl_spec.rb +19 -5
  126. data/spec/mongo/socket_spec.rb +1 -62
  127. data/spec/mongo/uri/srv_protocol_spec.rb +14 -20
  128. data/spec/mongo/uri_option_parsing_spec.rb +94 -8
  129. data/spec/mongo/uri_spec.rb +23 -10
  130. data/spec/mongo/write_concern_spec.rb +56 -3
  131. data/spec/spec_tests/change_streams_spec.rb +2 -1
  132. data/spec/spec_tests/cmap_spec.rb +1 -1
  133. data/spec/spec_tests/crud_spec.rb +12 -2
  134. data/spec/spec_tests/data/change_streams/change-streams-errors.yml +24 -1
  135. data/spec/spec_tests/data/change_streams/change-streams.yml +172 -3
  136. data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +1 -1
  137. data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -2
  138. data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -5
  139. data/spec/spec_tests/data/crud/read/aggregate-out.yml +0 -6
  140. data/spec/spec_tests/data/crud/read/count-empty.yml +29 -0
  141. data/spec/spec_tests/data/crud/write/bulkWrite-arrayFilters.yml +1 -0
  142. data/spec/spec_tests/data/crud/write/bulkWrite-collation.yml +101 -0
  143. data/spec/spec_tests/data/crud/write/bulkWrite.yml +401 -0
  144. data/spec/spec_tests/data/crud/write/insertMany.yml +58 -2
  145. data/spec/spec_tests/data/crud/write/updateMany-arrayFilters.yml +3 -0
  146. data/spec/spec_tests/data/crud/write/updateOne-arrayFilters.yml +6 -1
  147. data/spec/spec_tests/data/crud_v2/aggregate-merge.yml +103 -0
  148. data/spec/spec_tests/data/crud_v2/aggregate-out-readConcern.yml +110 -0
  149. data/spec/spec_tests/data/crud_v2/bulkWrite-arrayFilters.yml +81 -0
  150. data/spec/spec_tests/data/crud_v2/db-aggregate.yml +38 -0
  151. data/spec/spec_tests/data/crud_v2/updateWithPipelines.yml +92 -0
  152. data/spec/spec_tests/data/retryable_writes/insertOne-serverErrors.yml +2 -2
  153. data/spec/spec_tests/data/transactions/abort.yml +3 -0
  154. data/spec/spec_tests/data/transactions/bulk.yml +3 -8
  155. data/spec/spec_tests/data/transactions/causal-consistency.yml +3 -8
  156. data/spec/spec_tests/data/transactions/commit.yml +3 -1
  157. data/spec/spec_tests/data/transactions/count.yml +3 -0
  158. data/spec/spec_tests/data/transactions/delete.yml +3 -0
  159. data/spec/spec_tests/data/transactions/error-labels.yml +4 -1
  160. data/spec/spec_tests/data/transactions/errors-client.yml +56 -0
  161. data/spec/spec_tests/data/transactions/errors.yml +3 -0
  162. data/spec/spec_tests/data/transactions/findOneAndDelete.yml +3 -0
  163. data/spec/spec_tests/data/transactions/findOneAndReplace.yml +3 -0
  164. data/spec/spec_tests/data/transactions/findOneAndUpdate.yml +3 -0
  165. data/spec/spec_tests/data/transactions/insert.yml +3 -0
  166. data/spec/spec_tests/data/transactions/isolation.yml +3 -0
  167. data/spec/spec_tests/data/transactions/mongos-pin-auto.yml +1671 -0
  168. data/spec/spec_tests/data/transactions/mongos-recovery-token.yml +347 -0
  169. data/spec/spec_tests/data/transactions/pin-mongos.yml +557 -0
  170. data/spec/spec_tests/data/transactions/read-concern.yml +3 -0
  171. data/spec/spec_tests/data/transactions/read-pref.yml +3 -0
  172. data/spec/spec_tests/data/transactions/reads.yml +3 -0
  173. data/spec/spec_tests/data/transactions/retryable-abort.yml +5 -2
  174. data/spec/spec_tests/data/transactions/retryable-commit.yml +4 -1
  175. data/spec/spec_tests/data/transactions/retryable-writes.yml +3 -0
  176. data/spec/spec_tests/data/transactions/run-command.yml +3 -0
  177. data/spec/spec_tests/data/transactions/transaction-options.yml +6 -0
  178. data/spec/spec_tests/data/transactions/update.yml +3 -8
  179. data/spec/spec_tests/data/transactions/write-concern.yml +348 -38
  180. data/spec/spec_tests/data/transactions_api/callback-aborts.yml +6 -0
  181. data/spec/spec_tests/data/transactions_api/callback-commits.yml +5 -0
  182. data/spec/spec_tests/data/transactions_api/callback-retry.yml +7 -2
  183. data/spec/spec_tests/data/transactions_api/commit-retry.yml +70 -15
  184. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror-4.2.yml +3 -0
  185. data/spec/spec_tests/data/transactions_api/commit-transienttransactionerror.yml +3 -0
  186. data/spec/spec_tests/data/transactions_api/commit-writeconcernerror.yml +59 -109
  187. data/spec/spec_tests/data/transactions_api/commit.yml +5 -0
  188. data/spec/spec_tests/data/transactions_api/transaction-options.yml +10 -0
  189. data/spec/spec_tests/retryable_reads_spec.rb +5 -2
  190. data/spec/spec_tests/retryable_writes_spec.rb +5 -2
  191. data/spec/spec_tests/sdam_monitoring_spec.rb +3 -3
  192. data/spec/spec_tests/sdam_spec.rb +2 -2
  193. data/spec/spec_tests/transactions_api_spec.rb +1 -67
  194. data/spec/spec_tests/transactions_spec.rb +2 -66
  195. data/spec/support/authorization.rb +4 -0
  196. data/spec/support/change_streams.rb +30 -10
  197. data/spec/support/change_streams/operation.rb +27 -0
  198. data/spec/support/client_registry.rb +44 -25
  199. data/spec/support/cluster_config.rb +25 -14
  200. data/spec/support/cluster_tools.rb +32 -10
  201. data/spec/support/command_monitoring.rb +1 -1
  202. data/spec/support/common_shortcuts.rb +30 -0
  203. data/spec/support/connection_string.rb +8 -3
  204. data/spec/support/constraints.rb +34 -0
  205. data/spec/support/crud.rb +31 -16
  206. data/spec/support/crud/context.rb +23 -0
  207. data/spec/support/crud/operation.rb +311 -14
  208. data/spec/support/crud/spec.rb +2 -1
  209. data/spec/support/crud/test.rb +24 -27
  210. data/spec/support/crud/test_base.rb +22 -0
  211. data/spec/support/crud/verifier.rb +15 -1
  212. data/spec/support/event_subscriber.rb +12 -0
  213. data/spec/support/sdam_formatter_integration.rb +12 -6
  214. data/spec/support/shared/server_selector.rb +10 -0
  215. data/spec/support/shared/session.rb +13 -12
  216. data/spec/support/spec_config.rb +32 -22
  217. data/spec/support/spec_setup.rb +2 -2
  218. data/spec/support/transactions.rb +87 -0
  219. data/spec/support/transactions/context.rb +33 -0
  220. data/spec/support/transactions/operation.rb +99 -349
  221. data/spec/support/transactions/spec.rb +1 -3
  222. data/spec/support/transactions/test.rb +110 -49
  223. data/spec/support/utils.rb +74 -1
  224. metadata +52 -10
  225. metadata.gz.sig +0 -0
  226. data/spec/support/crud/read.rb +0 -265
  227. data/spec/support/crud/write.rb +0 -284
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b77d2eec3799354ea1153bac8ce5e4cee16cbab93774e9f877ee441f34aabe47
4
- data.tar.gz: 1f9c0ae6afcd403a90cebd1e31d1cc3cd4fb36a927ae6bbcaa1d089868755eb5
3
+ metadata.gz: '08673c7408cfc3fce9f682577a1156fe312c5f6806b4ea4ecef3d946dd7b0d3b'
4
+ data.tar.gz: 4811269ce3f01bd7508de797bf32c68bc7f6e858ca3949d12fa604dd011e41ab
5
5
  SHA512:
6
- metadata.gz: d06d245155dc239304713f24513285ca47c927a222e95d77a36065180ce6e8456510360ddf404bf628f8f59053a188331292b56896552cf29c8437454e8f158a
7
- data.tar.gz: 16cfd26917aa33baa71db76308a2c39e0f67c96dfd8981719d3f31c8dda815bdf2c569a5ff17e5bc2a45fdd7349182862adb838137e8e6046246e79f4237ace7
6
+ metadata.gz: fdfddf7f78f3eabb7d2c0249680ad0bacbfac5425f2ed8719a9dad96fc308cb969ee51edf290df7394a161819bb9c55f5180c765a2edf3f03ef3976c04f2be78
7
+ data.tar.gz: fe9b0f8aa59ce594ffef9da66a107e99f2d41d50ba29ae8fd318f15e53c9b574411d73c5d12450bdf4be7b6490820c847367a55157acdbbd8f59124cb74c075f
Binary file
data.tar.gz.sig CHANGED
Binary file
@@ -34,6 +34,7 @@ require 'mongo/bson'
34
34
  require 'mongo/semaphore'
35
35
  require 'mongo/options'
36
36
  require 'mongo/loggable'
37
+ require 'mongo/cluster_time'
37
38
  require 'mongo/monitoring'
38
39
  require 'mongo/logger'
39
40
  require 'mongo/retryable'
@@ -48,7 +48,7 @@ module Mongo
48
48
  user: user,
49
49
  db_name: database.name,
50
50
  session: session
51
- ).execute(next_primary)
51
+ ).execute(next_primary(nil, session))
52
52
  end
53
53
  end
54
54
 
@@ -83,7 +83,7 @@ module Mongo
83
83
  user_name: name,
84
84
  db_name: database.name,
85
85
  session: session
86
- ).execute(next_primary)
86
+ ).execute(next_primary(nil, session))
87
87
  end
88
88
  end
89
89
 
@@ -107,7 +107,7 @@ module Mongo
107
107
  user: user,
108
108
  db_name: database.name,
109
109
  session: session
110
- ).execute(next_primary)
110
+ ).execute(next_primary(nil, session))
111
111
  end
112
112
  end
113
113
 
@@ -136,7 +136,7 @@ module Mongo
136
136
  user_name: name,
137
137
  db_name: database.name,
138
138
  session: session
139
- ).execute(next_primary)
139
+ ).execute(next_primary(nil, session))
140
140
  end
141
141
  end
142
142
 
@@ -23,7 +23,7 @@ require 'mongo/bulk_write/result_combiner'
23
23
  module Mongo
24
24
  class BulkWrite
25
25
  extend Forwardable
26
- include Retryable
26
+ include Operation::Unpinnable
27
27
 
28
28
  # @return [ Mongo::Collection ] collection The collection.
29
29
  attr_reader :collection
@@ -38,6 +38,8 @@ module Mongo
38
38
  def_delegators :@collection,
39
39
  :database,
40
40
  :cluster,
41
+ :write_with_retry,
42
+ :nro_write_with_retry,
41
43
  :next_primary
42
44
 
43
45
  def_delegators :database, :client
@@ -58,6 +60,7 @@ module Mongo
58
60
  client.send(:with_session, @options) do |session|
59
61
  operations.each do |operation|
60
62
  if single_statement?(operation)
63
+ write_concern = write_concern(session)
61
64
  write_with_retry(session, write_concern) do |server, txn_num|
62
65
  execute_operation(
63
66
  operation.keys.first,
@@ -69,7 +72,7 @@ module Mongo
69
72
  txn_num)
70
73
  end
71
74
  else
72
- legacy_write_with_retry do |server|
75
+ nro_write_with_retry(session, write_concern) do |server|
73
76
  execute_operation(
74
77
  operation.keys.first,
75
78
  operation.values.flatten,
@@ -139,9 +142,10 @@ module Mongo
139
142
  # @return [ WriteConcern ] The write concern.
140
143
  #
141
144
  # @since 2.1.0
142
- def write_concern
145
+ def write_concern(session = nil)
143
146
  @write_concern ||= options[:write_concern] ?
144
- WriteConcern.get(options[:write_concern]) : collection.write_concern
147
+ WriteConcern.get(options[:write_concern]) :
148
+ collection.write_concern_with_session(session)
145
149
  end
146
150
 
147
151
  private
@@ -158,7 +162,7 @@ module Mongo
158
162
  {
159
163
  :db_name => database.name,
160
164
  :coll_name => collection.name,
161
- :write_concern => write_concern,
165
+ :write_concern => write_concern(session),
162
166
  :ordered => ordered?,
163
167
  :operation_id => operation_id,
164
168
  :bypass_document_validation => !!options[:bypass_document_validation],
@@ -171,15 +175,17 @@ module Mongo
171
175
  def execute_operation(name, values, server, operation_id, result_combiner, session, txn_num = nil)
172
176
  raise Error::UnsupportedCollation.new if op_combiner.has_collation && !server.features.collation_enabled?
173
177
  raise Error::UnsupportedArrayFilters.new if op_combiner.has_array_filters && !server.features.array_filters_enabled?
174
- begin
178
+ unpin_maybe(session) do
175
179
  if values.size > server.max_write_batch_size
176
180
  split_execute(name, values, server, operation_id, result_combiner, session, txn_num)
177
181
  else
178
182
  result = send(name, values, server, operation_id, session, txn_num)
179
183
  result_combiner.combine!(result, values.size)
180
184
  end
181
- rescue Error::MaxBSONSize, Error::MaxMessageSize => e
182
- raise e if values.size <= 1
185
+ end
186
+ rescue Error::MaxBSONSize, Error::MaxMessageSize => e
187
+ raise e if values.size <= 1
188
+ unpin_maybe(session) do
183
189
  split_execute(name, values, server, operation_id, result_combiner, session, txn_num)
184
190
  end
185
191
  end
@@ -180,7 +180,7 @@ module Mongo
180
180
  #
181
181
  # @since 2.1.0
182
182
  def validate!
183
- if @results[Error::WRITE_ERRORS] || @results[Error::WRITE_CONCERN_ERRORS]
183
+ if @results['writeErrors'] || @results['writeConcernErrors']
184
184
  raise Error::BulkWriteError.new(@results)
185
185
  else
186
186
  self
@@ -112,7 +112,7 @@ module Mongo
112
112
  def combine_write_errors!(result)
113
113
  if write_errors = result.aggregate_write_errors(count)
114
114
  results.merge!(
115
- Error::WRITE_ERRORS => ((results[Error::WRITE_ERRORS] || []) << write_errors).flatten
115
+ 'writeErrors' => ((results['writeErrors'] || []) << write_errors).flatten
116
116
  )
117
117
  else
118
118
  result.validate!
@@ -121,7 +121,7 @@ module Mongo
121
121
 
122
122
  def combine_write_concern_errors!(result)
123
123
  if write_concern_errors = result.aggregate_write_concern_errors(count)
124
- results[Error::WRITE_CONCERN_ERRORS] = (results[Error::WRITE_CONCERN_ERRORS] || []) +
124
+ results['writeConcernErrors'] = (results['writeConcernErrors'] || []) +
125
125
  write_concern_errors
126
126
  end
127
127
  end
@@ -56,8 +56,10 @@ module Mongo
56
56
  #
57
57
  # @since 2.1.0
58
58
  DELETE_MANY_TRANSFORM = ->(doc){
59
- { Operation::Q => doc[:filter],
60
- Operation::LIMIT => 0 }.tap do |d|
59
+ {
60
+ Operation::Q => doc[:filter],
61
+ Operation::LIMIT => 0,
62
+ }.tap do |d|
61
63
  d[Operation::COLLATION] = doc[:collation] if doc[:collation]
62
64
  end
63
65
  }
@@ -66,8 +68,10 @@ module Mongo
66
68
  #
67
69
  # @since 2.1.0
68
70
  DELETE_ONE_TRANSFORM = ->(doc){
69
- { Operation::Q => doc[:filter],
70
- Operation::LIMIT => 1 }.tap do |d|
71
+ {
72
+ Operation::Q => doc[:filter],
73
+ Operation::LIMIT => 1,
74
+ }.tap do |d|
71
75
  d[Operation::COLLATION] = doc[:collation] if doc[:collation]
72
76
  end
73
77
  }
@@ -86,9 +90,10 @@ module Mongo
86
90
  {
87
91
  Operation::Q => doc[:filter],
88
92
  Operation::U => doc[:replacement],
89
- Operation::MULTI => false,
90
- Operation::UPSERT => doc.fetch(:upsert, false)
91
93
  }.tap do |d|
94
+ if doc[:upsert]
95
+ d[:upsert] = true
96
+ end
92
97
  d[Operation::COLLATION] = doc[:collation] if doc[:collation]
93
98
  end
94
99
  }
@@ -101,8 +106,10 @@ module Mongo
101
106
  Operation::Q => doc[:filter],
102
107
  Operation::U => doc[:update],
103
108
  Operation::MULTI => true,
104
- Operation::UPSERT => doc.fetch(:upsert, false)
105
109
  }.tap do |d|
110
+ if doc[:upsert]
111
+ d[:upsert] = true
112
+ end
106
113
  d[Operation::COLLATION] = doc[:collation] if doc[:collation]
107
114
  d[Operation::ARRAY_FILTERS] = doc[:array_filters] if doc[:array_filters]
108
115
  end
@@ -115,9 +122,10 @@ module Mongo
115
122
  {
116
123
  Operation::Q => doc[:filter],
117
124
  Operation::U => doc[:update],
118
- Operation::MULTI => false,
119
- Operation::UPSERT => doc.fetch(:upsert, false)
120
125
  }.tap do |d|
126
+ if doc[:upsert]
127
+ d[:upsert] = true
128
+ end
121
129
  d[Operation::COLLATION] = doc[:collation] if doc[:collation]
122
130
  d[Operation::ARRAY_FILTERS] = doc[:array_filters] if doc[:array_filters]
123
131
  end
@@ -27,8 +27,22 @@ module Mongo
27
27
  #
28
28
  # @since 2.1.0
29
29
  CRUD_OPTIONS = [
30
- :database, :read, :write, :retry_reads, :retry_writes,
31
- :max_read_retries, :read_retry_interval, :max_write_retries,
30
+ :database,
31
+ :read, :read_concern,
32
+ :write, :write_concern,
33
+ :retry_reads, :max_read_retries, :read_retry_interval,
34
+ :retry_writes, :max_write_retries,
35
+
36
+ # Options which cannot currently be here:
37
+ #
38
+ # :server_selection_timeout
39
+ # Server selection timeout is used by cluster constructor to figure out
40
+ # how long to wait for initial scan in compatibility mode, but once
41
+ # the cluster is initialized it no longer uses this timeout.
42
+ # Unfortunately server selector reads server selection timeout out of
43
+ # the cluster, and this behavior is required by Cluster#next_primary
44
+ # which takes no arguments. When next_primary is removed we can revsit
45
+ # using the same cluster object with different server selection timeouts.
32
46
  ].freeze
33
47
 
34
48
  # Valid client options.
@@ -39,6 +53,7 @@ module Mongo
39
53
  :auth_mech,
40
54
  :auth_mech_properties,
41
55
  :auth_source,
56
+ :cleanup,
42
57
  :compressors,
43
58
  :connect,
44
59
  :connect_timeout,
@@ -84,6 +99,7 @@ module Mongo
84
99
  :user,
85
100
  :wait_queue_timeout,
86
101
  :write,
102
+ :write_concern,
87
103
  :zlib_compression_level,
88
104
  ].freeze
89
105
 
@@ -231,6 +247,11 @@ module Mongo
231
247
  # done by this client or servers under it. Note: setting this option
232
248
  # to false will make the client non-functional. It is intended for
233
249
  # use in tests which manually invoke SDAM state transitions.
250
+ # @option options [ true | false ] :cleanup For internal driver use only.
251
+ # Set to false to prevent endSessions command being sent to the server
252
+ # to clean up server sessions when the cluster is disconnected, and to
253
+ # to not start the periodic executor. If :monitoring_io is false,
254
+ # :cleanup automatically defaults to false as well.
234
255
  # @option options [ String ] :password The user's password.
235
256
  # @option options [ String ] :platform Platform information to include in
236
257
  # the metadata printed to the mongod logs upon establishing a connection
@@ -334,8 +355,10 @@ module Mongo
334
355
  # @option options [ String ] :user The user name.
335
356
  # @option options [ Float ] :wait_queue_timeout The time to wait, in
336
357
  # seconds, in the connection pool for a connection to be checked in.
337
- # @option options [ Hash ] :write The write concern options. Can be :w =>
338
- # Integer|String, :fsync => Boolean, :j => Boolean.
358
+ # @option options [ Hash ] :write Deprecated. Equivalent to :write_concern
359
+ # option.
360
+ # @option options [ Hash ] :write_concern The write concern options.
361
+ # Can be :w => Integer|String, :fsync => Boolean, :j => Boolean.
339
362
  # @option options [ Integer ] :zlib_compression_level The Zlib compression level to use, if using compression.
340
363
  # See Ruby's Zlib module for valid levels.
341
364
  #
@@ -347,13 +370,18 @@ module Mongo
347
370
  options = {}
348
371
  end
349
372
 
350
- Lint.validate_underscore_read_preference(options[:read])
351
- Lint.validate_read_concern_option(options[:read_concern])
352
-
353
373
  if addresses_or_uri.is_a?(::String)
354
374
  uri = URI.get(addresses_or_uri, options)
355
375
  addresses = uri.servers
356
- options = uri.client_options.merge(options)
376
+ uri_options = uri.client_options.dup
377
+ # Special handing for :write and :write_concern: allow client Ruby
378
+ # options to override URI options, even when the Ruby option uses the
379
+ # deprecated :write key and the URI option uses the current
380
+ # :write_concern key
381
+ if options[:write]
382
+ uri_options.delete(:write_concern)
383
+ end
384
+ options = uri_options.merge(options)
357
385
  else
358
386
  addresses = addresses_or_uri
359
387
  end
@@ -368,16 +396,31 @@ module Mongo
368
396
  # Special handling for sdam_proc as it is only used during client
369
397
  # construction
370
398
  sdam_proc = options.delete(:sdam_proc)
371
- @options = validate_options!(Database::DEFAULT_OPTIONS.merge(options)).freeze
399
+
400
+ @options = validate_new_options!(Database::DEFAULT_OPTIONS.merge(options))
401
+ =begin WriteConcern object support
402
+ if @options[:write_concern].is_a?(WriteConcern::Base)
403
+ # Cache the instance so that we do not needlessly reconstruct it.
404
+ @write_concern = @options[:write_concern]
405
+ @options[:write_concern] = @write_concern.options
406
+ end
407
+ =end
408
+ @options.freeze
409
+ validate_options!
410
+
372
411
  @database = Database.new(self, @options[:database], @options)
412
+
373
413
  # Temporarily set monitoring so that event subscriptions can be
374
414
  # set up without there being a cluster
375
415
  @monitoring = Monitoring.new(@options)
416
+
376
417
  if sdam_proc
377
418
  sdam_proc.call(self)
378
419
  end
420
+
379
421
  @server_selection_semaphore = Semaphore.new
380
422
  @cluster = Cluster.new(addresses, @monitoring, cluster_options)
423
+
381
424
  # Unset monitoring, it will be taken out of cluster from now on
382
425
  remove_instance_variable('@monitoring')
383
426
 
@@ -472,7 +515,11 @@ module Mongo
472
515
  #
473
516
  # @since 2.5.0
474
517
  def server_selector
475
- @server_selector ||= ServerSelector.get(read_preference || ServerSelector::PRIMARY)
518
+ @server_selector ||= if read_preference
519
+ ServerSelector.get(read_preference)
520
+ else
521
+ ServerSelector.primary
522
+ end
476
523
  end
477
524
 
478
525
  # Get the read preference from the options passed to the client.
@@ -532,8 +579,7 @@ module Mongo
532
579
  # @since 2.0.0
533
580
  def with(new_options = Options::Redacted.new)
534
581
  clone.tap do |client|
535
- opts = validate_options!(new_options)
536
- client.options.update(opts)
582
+ opts = client.update_options(new_options)
537
583
  Database.create(client)
538
584
  # We can't use the same cluster if some options that would affect it
539
585
  # have changed.
@@ -543,6 +589,36 @@ module Mongo
543
589
  end
544
590
  end
545
591
 
592
+ # Updates this client's options from new_options, validating all options.
593
+ #
594
+ # The new options may be transformed according to various rules.
595
+ # The final hash of options actually applied to the client is returned.
596
+ #
597
+ # If options fail validation, this method may warn or raise an exception.
598
+ # If this method raises an exception, the client should be discarded
599
+ # (similarly to if a constructor raised an exception).
600
+ #
601
+ # @param [ Hash ] new_options The new options to use.
602
+ #
603
+ # @return [ Hash ] Modified new options written into the client.
604
+ #
605
+ # @api private
606
+ def update_options(new_options)
607
+ validate_new_options!(new_options).tap do |opts|
608
+ # Our options are frozen
609
+ options = @options.dup
610
+ if options[:write] && opts[:write_concern]
611
+ options.delete(:write)
612
+ end
613
+ if options[:write_concern] && opts[:write]
614
+ options.delete(:write_concern)
615
+ end
616
+ options.update(opts)
617
+ @options = options.freeze
618
+ validate_options!
619
+ end
620
+ end
621
+
546
622
  # Get the read concern for this client.
547
623
  #
548
624
  # @example Get the client read concern.
@@ -566,7 +642,7 @@ module Mongo
566
642
  #
567
643
  # @since 2.0.0
568
644
  def write_concern
569
- @write_concern ||= WriteConcern.get(options[:write])
645
+ @write_concern ||= WriteConcern.get(options[:write_concern] || options[:write])
570
646
  end
571
647
 
572
648
  # Close all connections.
@@ -614,7 +690,7 @@ module Mongo
614
690
  #
615
691
  # @since 2.0.5
616
692
  def database_names(filter = {}, opts = {})
617
- list_databases(filter, true, opts).collect{ |info| info[Database::NAME] }
693
+ list_databases(filter, true, opts).collect{ |info| info['name'] }
618
694
  end
619
695
 
620
696
  # Get info for each database.
@@ -633,7 +709,7 @@ module Mongo
633
709
  cmd = { listDatabases: 1 }
634
710
  cmd[:nameOnly] = !!name_only
635
711
  cmd[:filter] = filter unless filter.empty?
636
- use(Database::ADMIN).database.read_command(cmd, opts).first[Database::DATABASES]
712
+ use(Database::ADMIN).command(cmd, opts).first[Database::DATABASES]
637
713
  end
638
714
 
639
715
  # Returns a list of Mongo::Database objects.
@@ -754,8 +830,14 @@ module Mongo
754
830
  end
755
831
  end
756
832
 
757
- def validate_options!(opts = Options::Redacted.new)
833
+ # Validates options in the provided argument for validity.
834
+ # The argument may contain a subset of options that the client will
835
+ # eventually have; this method validates each of the provided options
836
+ # but does not check for interactions between combinations of options.
837
+ def validate_new_options!(opts = Options::Redacted.new)
758
838
  return Options::Redacted.new unless opts
839
+ Lint.validate_underscore_read_preference(opts[:read])
840
+ Lint.validate_read_concern_option(opts[:read_concern])
759
841
  opts.each.inject(Options::Redacted.new) do |_options, (k, v)|
760
842
  key = k.to_sym
761
843
  if VALID_OPTIONS.include?(key)
@@ -774,6 +856,15 @@ module Mongo
774
856
  end
775
857
  end
776
858
 
859
+ # Validates all options after they are set on the client.
860
+ # This method is intended to catch combinations of options which do are
861
+ # not allowed.
862
+ def validate_options!
863
+ if options[:write] && options[:write_concern] && options[:write] != options[:write_concern]
864
+ raise ArgumentError, "If :write and :write_concern are both given, they must be identical: #{options.inspect}"
865
+ end
866
+ end
867
+
777
868
  def valid_compressors(compressors)
778
869
  compressors.select do |compressor|
779
870
  if !VALID_COMPRESSORS.include?(compressor)