mongo 2.5.3 → 2.6.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 (394) hide show
  1. checksums.yaml +5 -5
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/LICENSE +1 -1
  5. data/README.md +3 -2
  6. data/lib/mongo.rb +2 -2
  7. data/lib/mongo/address.rb +10 -2
  8. data/lib/mongo/address/ipv4.rb +1 -1
  9. data/lib/mongo/address/ipv6.rb +26 -5
  10. data/lib/mongo/address/unix.rb +1 -1
  11. data/lib/mongo/auth.rb +10 -3
  12. data/lib/mongo/auth/cr.rb +4 -1
  13. data/lib/mongo/auth/cr/conversation.rb +4 -1
  14. data/lib/mongo/auth/ldap.rb +1 -1
  15. data/lib/mongo/auth/ldap/conversation.rb +1 -1
  16. data/lib/mongo/auth/roles.rb +1 -1
  17. data/lib/mongo/auth/scram.rb +24 -7
  18. data/lib/mongo/auth/scram/conversation.rb +52 -19
  19. data/lib/mongo/auth/stringprep.rb +114 -0
  20. data/lib/mongo/auth/stringprep/profiles/sasl.rb +73 -0
  21. data/lib/mongo/auth/stringprep/tables.rb +3232 -0
  22. data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +174 -0
  23. data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +1170 -0
  24. data/lib/mongo/auth/user.rb +14 -3
  25. data/lib/mongo/auth/user/view.rb +1 -1
  26. data/lib/mongo/auth/x509.rb +1 -1
  27. data/lib/mongo/auth/x509/conversation.rb +1 -1
  28. data/lib/mongo/bson.rb +1 -1
  29. data/lib/mongo/bulk_write.rb +8 -8
  30. data/lib/mongo/bulk_write/combineable.rb +1 -1
  31. data/lib/mongo/bulk_write/ordered_combiner.rb +1 -1
  32. data/lib/mongo/bulk_write/result.rb +1 -1
  33. data/lib/mongo/bulk_write/result_combiner.rb +4 -4
  34. data/lib/mongo/bulk_write/transformable.rb +1 -1
  35. data/lib/mongo/bulk_write/unordered_combiner.rb +1 -1
  36. data/lib/mongo/bulk_write/validatable.rb +1 -1
  37. data/lib/mongo/client.rb +115 -24
  38. data/lib/mongo/cluster.rb +17 -10
  39. data/lib/mongo/cluster/app_metadata.rb +7 -1
  40. data/lib/mongo/cluster/periodic_executor.rb +1 -1
  41. data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -1
  42. data/lib/mongo/cluster/topology.rb +12 -2
  43. data/lib/mongo/cluster/topology/replica_set.rb +9 -1
  44. data/lib/mongo/cluster/topology/sharded.rb +1 -1
  45. data/lib/mongo/cluster/topology/single.rb +1 -1
  46. data/lib/mongo/cluster/topology/unknown.rb +1 -1
  47. data/lib/mongo/collection.rb +75 -19
  48. data/lib/mongo/collection/view.rb +1 -1
  49. data/lib/mongo/collection/view/aggregation.rb +1 -1
  50. data/lib/mongo/collection/view/builder.rb +1 -1
  51. data/lib/mongo/collection/view/builder/aggregation.rb +3 -3
  52. data/lib/mongo/collection/view/builder/find_command.rb +1 -1
  53. data/lib/mongo/collection/view/builder/flags.rb +1 -1
  54. data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
  55. data/lib/mongo/collection/view/builder/modifiers.rb +1 -1
  56. data/lib/mongo/collection/view/builder/op_query.rb +1 -1
  57. data/lib/mongo/collection/view/change_stream.rb +193 -17
  58. data/lib/mongo/collection/view/change_stream/retryable.rb +3 -20
  59. data/lib/mongo/collection/view/explainable.rb +1 -1
  60. data/lib/mongo/collection/view/immutable.rb +1 -1
  61. data/lib/mongo/collection/view/iterable.rb +2 -2
  62. data/lib/mongo/collection/view/map_reduce.rb +1 -1
  63. data/lib/mongo/collection/view/readable.rb +108 -29
  64. data/lib/mongo/collection/view/writable.rb +3 -3
  65. data/lib/mongo/cursor.rb +44 -4
  66. data/lib/mongo/cursor/builder.rb +1 -1
  67. data/lib/mongo/cursor/builder/get_more_command.rb +1 -1
  68. data/lib/mongo/cursor/builder/kill_cursors_command.rb +1 -1
  69. data/lib/mongo/cursor/builder/op_get_more.rb +1 -1
  70. data/lib/mongo/cursor/builder/op_kill_cursors.rb +1 -1
  71. data/lib/mongo/database.rb +46 -3
  72. data/lib/mongo/database/view.rb +11 -11
  73. data/lib/mongo/dbref.rb +1 -1
  74. data/lib/mongo/error.rb +57 -1
  75. data/lib/mongo/error/bulk_write_error.rb +2 -2
  76. data/lib/mongo/error/change_stream_resumable.rb +37 -0
  77. data/lib/mongo/error/closed_stream.rb +1 -1
  78. data/lib/mongo/error/extra_file_chunk.rb +1 -1
  79. data/lib/mongo/error/failed_stringprep_validation.rb +38 -0
  80. data/lib/mongo/error/file_not_found.rb +1 -1
  81. data/lib/mongo/error/insufficient_iteration_count.rb +38 -0
  82. data/lib/mongo/error/invalid_application_name.rb +1 -1
  83. data/lib/mongo/error/invalid_bulk_operation.rb +1 -1
  84. data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -1
  85. data/lib/mongo/error/invalid_collection_name.rb +1 -1
  86. data/lib/mongo/error/invalid_database_name.rb +1 -1
  87. data/lib/mongo/error/invalid_document.rb +1 -1
  88. data/lib/mongo/error/invalid_file.rb +1 -1
  89. data/lib/mongo/error/invalid_file_revision.rb +1 -1
  90. data/lib/mongo/error/invalid_min_pool_size.rb +1 -1
  91. data/lib/mongo/error/invalid_nonce.rb +1 -1
  92. data/lib/mongo/error/invalid_read_option.rb +35 -0
  93. data/lib/mongo/error/invalid_replacement_document.rb +1 -1
  94. data/lib/mongo/error/invalid_server_preference.rb +1 -1
  95. data/lib/mongo/error/invalid_session.rb +1 -1
  96. data/lib/mongo/error/invalid_signature.rb +1 -1
  97. data/lib/mongo/error/invalid_transaction_operation.rb +82 -0
  98. data/lib/mongo/error/invalid_txt_record.rb +1 -1
  99. data/lib/mongo/error/invalid_update_document.rb +1 -1
  100. data/lib/mongo/error/invalid_uri.rb +1 -1
  101. data/lib/mongo/error/invalid_write_concern.rb +1 -1
  102. data/lib/mongo/error/max_bson_size.rb +1 -1
  103. data/lib/mongo/error/max_message_size.rb +1 -1
  104. data/lib/mongo/error/mismatched_domain.rb +1 -1
  105. data/lib/mongo/error/missing_file_chunk.rb +1 -1
  106. data/lib/mongo/error/missing_resume_token.rb +1 -1
  107. data/lib/mongo/error/multi_index_drop.rb +1 -1
  108. data/lib/mongo/error/need_primary_server.rb +1 -1
  109. data/lib/mongo/error/no_server_available.rb +1 -1
  110. data/lib/mongo/error/no_srv_records.rb +1 -1
  111. data/lib/mongo/error/operation_failure.rb +108 -14
  112. data/lib/mongo/error/parser.rb +50 -1
  113. data/lib/mongo/error/socket_error.rb +5 -2
  114. data/lib/mongo/error/socket_timeout_error.rb +5 -2
  115. data/lib/mongo/error/unchangeable_collection_option.rb +1 -1
  116. data/lib/mongo/error/unexpected_chunk_length.rb +1 -1
  117. data/lib/mongo/error/unexpected_response.rb +1 -1
  118. data/lib/mongo/error/unknown_payload_type.rb +1 -1
  119. data/lib/mongo/error/unsupported_array_filters.rb +1 -1
  120. data/lib/mongo/error/unsupported_collation.rb +1 -1
  121. data/lib/mongo/error/unsupported_features.rb +1 -1
  122. data/lib/mongo/error/unsupported_message_type.rb +1 -1
  123. data/lib/mongo/error/write_retryable.rb +27 -0
  124. data/lib/mongo/event.rb +10 -9
  125. data/lib/mongo/event/base.rb +33 -0
  126. data/lib/mongo/event/description_changed.rb +2 -2
  127. data/lib/mongo/event/listeners.rb +1 -1
  128. data/lib/mongo/event/member_discovered.rb +4 -2
  129. data/lib/mongo/event/primary_elected.rb +2 -2
  130. data/lib/mongo/event/publisher.rb +1 -1
  131. data/lib/mongo/event/standalone_discovered.rb +2 -2
  132. data/lib/mongo/event/subscriber.rb +1 -1
  133. data/lib/mongo/grid.rb +1 -1
  134. data/lib/mongo/grid/file.rb +1 -1
  135. data/lib/mongo/grid/file/chunk.rb +3 -3
  136. data/lib/mongo/grid/file/info.rb +26 -3
  137. data/lib/mongo/grid/fs_bucket.rb +1 -1
  138. data/lib/mongo/grid/stream.rb +1 -1
  139. data/lib/mongo/grid/stream/read.rb +1 -1
  140. data/lib/mongo/grid/stream/write.rb +1 -1
  141. data/lib/mongo/index.rb +1 -1
  142. data/lib/mongo/index/view.rb +1 -1
  143. data/lib/mongo/loggable.rb +1 -1
  144. data/lib/mongo/logger.rb +1 -1
  145. data/lib/mongo/monitoring.rb +99 -62
  146. data/lib/mongo/monitoring/command_log_subscriber.rb +2 -2
  147. data/lib/mongo/monitoring/event.rb +2 -1
  148. data/lib/mongo/monitoring/event/command_failed.rb +19 -6
  149. data/lib/mongo/monitoring/event/command_started.rb +14 -3
  150. data/lib/mongo/monitoring/event/command_succeeded.rb +5 -3
  151. data/lib/mongo/monitoring/event/secure.rb +1 -1
  152. data/lib/mongo/monitoring/event/server_closed.rb +2 -2
  153. data/lib/mongo/monitoring/event/server_description_changed.rb +2 -2
  154. data/lib/mongo/monitoring/event/server_opening.rb +11 -2
  155. data/lib/mongo/monitoring/event/topology_changed.rb +13 -2
  156. data/lib/mongo/monitoring/event/topology_closed.rb +2 -2
  157. data/lib/mongo/monitoring/event/topology_opening.rb +11 -2
  158. data/lib/mongo/monitoring/publishable.rb +10 -6
  159. data/lib/mongo/monitoring/sdam_log_subscriber.rb +1 -1
  160. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +1 -1
  161. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +1 -1
  162. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +1 -1
  163. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +1 -1
  164. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +1 -1
  165. data/lib/mongo/operation/aggregate/op_msg.rb +3 -0
  166. data/lib/mongo/operation/create/op_msg.rb +9 -0
  167. data/lib/mongo/operation/create_index/op_msg.rb +9 -0
  168. data/lib/mongo/operation/create_user/command.rb +1 -1
  169. data/lib/mongo/operation/create_user/op_msg.rb +10 -1
  170. data/lib/mongo/operation/delete/op_msg.rb +3 -0
  171. data/lib/mongo/operation/distinct/op_msg.rb +9 -0
  172. data/lib/mongo/operation/drop/op_msg.rb +9 -0
  173. data/lib/mongo/operation/drop_database/op_msg.rb +9 -0
  174. data/lib/mongo/operation/drop_index/op_msg.rb +9 -0
  175. data/lib/mongo/operation/explain/op_msg.rb +3 -0
  176. data/lib/mongo/operation/find/op_msg.rb +3 -0
  177. data/lib/mongo/operation/get_more.rb +1 -1
  178. data/lib/mongo/operation/get_more/command.rb +1 -1
  179. data/lib/mongo/operation/get_more/legacy.rb +1 -1
  180. data/lib/mongo/operation/get_more/op_msg.rb +3 -0
  181. data/lib/mongo/operation/indexes/op_msg.rb +3 -0
  182. data/lib/mongo/operation/indexes/result.rb +1 -1
  183. data/lib/mongo/operation/insert/bulk_result.rb +32 -2
  184. data/lib/mongo/operation/insert/op_msg.rb +3 -0
  185. data/lib/mongo/operation/insert/result.rb +1 -1
  186. data/lib/mongo/operation/kill_cursors/op_msg.rb +9 -0
  187. data/lib/mongo/operation/list_collections/op_msg.rb +3 -0
  188. data/lib/mongo/operation/list_collections/result.rb +5 -1
  189. data/lib/mongo/operation/map_reduce/op_msg.rb +3 -0
  190. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  191. data/lib/mongo/operation/parallel_scan/op_msg.rb +3 -0
  192. data/lib/mongo/operation/remove_user/op_msg.rb +9 -0
  193. data/lib/mongo/operation/result.rb +27 -14
  194. data/lib/mongo/operation/shared/executable.rb +1 -0
  195. data/lib/mongo/operation/shared/sessions_supported.rb +78 -7
  196. data/lib/mongo/operation/shared/specifiable.rb +18 -2
  197. data/lib/mongo/operation/shared/write_concern_supported.rb +1 -1
  198. data/lib/mongo/operation/update/op_msg.rb +3 -0
  199. data/lib/mongo/operation/update_user/command.rb +1 -1
  200. data/lib/mongo/operation/update_user/op_msg.rb +10 -1
  201. data/lib/mongo/operation/users_info/op_msg.rb +3 -0
  202. data/lib/mongo/options.rb +1 -1
  203. data/lib/mongo/options/mapper.rb +1 -1
  204. data/lib/mongo/options/redacted.rb +1 -1
  205. data/lib/mongo/protocol/bit_vector.rb +1 -1
  206. data/lib/mongo/protocol/compressed.rb +1 -1
  207. data/lib/mongo/protocol/delete.rb +1 -1
  208. data/lib/mongo/protocol/get_more.rb +7 -7
  209. data/lib/mongo/protocol/insert.rb +1 -1
  210. data/lib/mongo/protocol/kill_cursors.rb +1 -1
  211. data/lib/mongo/protocol/message.rb +5 -5
  212. data/lib/mongo/protocol/msg.rb +9 -7
  213. data/lib/mongo/protocol/query.rb +1 -1
  214. data/lib/mongo/protocol/registry.rb +1 -1
  215. data/lib/mongo/protocol/reply.rb +10 -10
  216. data/lib/mongo/protocol/serializers.rb +1 -1
  217. data/lib/mongo/protocol/update.rb +1 -1
  218. data/lib/mongo/retryable.rb +22 -14
  219. data/lib/mongo/server.rb +1 -1
  220. data/lib/mongo/server/connectable.rb +1 -1
  221. data/lib/mongo/server/connection.rb +16 -4
  222. data/lib/mongo/server/connection_pool.rb +1 -1
  223. data/lib/mongo/server/connection_pool/queue.rb +1 -1
  224. data/lib/mongo/server/context.rb +1 -1
  225. data/lib/mongo/server/description.rb +14 -2
  226. data/lib/mongo/server/description/features.rb +10 -9
  227. data/lib/mongo/server/description/inspector.rb +1 -1
  228. data/lib/mongo/server/description/inspector/description_changed.rb +1 -1
  229. data/lib/mongo/server/description/inspector/member_discovered.rb +1 -1
  230. data/lib/mongo/server/description/inspector/primary_elected.rb +1 -1
  231. data/lib/mongo/server/description/inspector/standalone_discovered.rb +1 -1
  232. data/lib/mongo/server/monitor.rb +15 -3
  233. data/lib/mongo/server/monitor/connection.rb +1 -1
  234. data/lib/mongo/server_selector.rb +1 -1
  235. data/lib/mongo/server_selector/nearest.rb +1 -1
  236. data/lib/mongo/server_selector/primary.rb +1 -1
  237. data/lib/mongo/server_selector/primary_preferred.rb +1 -1
  238. data/lib/mongo/server_selector/secondary.rb +1 -1
  239. data/lib/mongo/server_selector/secondary_preferred.rb +1 -1
  240. data/lib/mongo/server_selector/selectable.rb +7 -2
  241. data/lib/mongo/session.rb +389 -12
  242. data/lib/mongo/session/server_session.rb +7 -2
  243. data/lib/mongo/session/session_pool.rb +1 -1
  244. data/lib/mongo/socket.rb +1 -1
  245. data/lib/mongo/socket/ssl.rb +1 -1
  246. data/lib/mongo/socket/tcp.rb +1 -1
  247. data/lib/mongo/socket/unix.rb +1 -1
  248. data/lib/mongo/uri.rb +6 -4
  249. data/lib/mongo/uri/srv_protocol.rb +1 -1
  250. data/lib/mongo/version.rb +2 -2
  251. data/lib/mongo/write_concern.rb +1 -1
  252. data/lib/mongo/write_concern/acknowledged.rb +1 -1
  253. data/lib/mongo/write_concern/normalizable.rb +1 -1
  254. data/lib/mongo/write_concern/unacknowledged.rb +1 -1
  255. data/mongo.gemspec +4 -1
  256. data/spec/atlas/atlas_connectivity_spec.rb +54 -0
  257. data/spec/integration/bulk_insert_spec.rb +78 -0
  258. data/spec/integration/change_stream_spec.rb +365 -0
  259. data/spec/integration/command_monitoring_spec.rb +92 -0
  260. data/spec/lite_spec_helper.rb +63 -0
  261. data/spec/mongo/address/ipv6_spec.rb +29 -1
  262. data/spec/mongo/address_spec.rb +34 -0
  263. data/spec/mongo/auth/scram/conversation_spec.rb +326 -120
  264. data/spec/mongo/auth/scram/negotiation_spec.rb +574 -0
  265. data/spec/mongo/auth/scram_spec.rb +107 -38
  266. data/spec/mongo/auth/stringprep/profiles/sasl_spec.rb +113 -0
  267. data/spec/mongo/auth/stringprep_spec.rb +188 -0
  268. data/spec/mongo/auth/user/view_spec.rb +5 -2
  269. data/spec/mongo/auth/user_spec.rb +1 -1
  270. data/spec/mongo/bulk_write/result_spec.rb +120 -0
  271. data/spec/mongo/bulk_write_spec.rb +42 -2
  272. data/spec/mongo/client_spec.rb +121 -9
  273. data/spec/mongo/cluster/app_metadata_spec.rb +14 -1
  274. data/spec/mongo/cluster/topology_spec.rb +1 -23
  275. data/spec/mongo/collection/view/change_stream_spec.rb +62 -180
  276. data/spec/mongo/collection_spec.rb +45 -12
  277. data/spec/mongo/cursor/builder/get_more_command_spec.rb +7 -7
  278. data/spec/mongo/cursor_spec.rb +2 -2
  279. data/spec/mongo/database_spec.rb +3 -3
  280. data/spec/mongo/docs_examples_spec.rb +194 -0
  281. data/spec/mongo/error/operation_failure_spec.rb +152 -0
  282. data/spec/mongo/error/parser_spec.rb +127 -0
  283. data/spec/mongo/grid/fs_bucket_spec.rb +32 -0
  284. data/spec/mongo/grid/stream/write_spec.rb +40 -1
  285. data/spec/mongo/monitoring/event/command_failed_spec.rb +30 -0
  286. data/spec/mongo/monitoring/event/command_started_spec.rb +26 -4
  287. data/spec/mongo/monitoring/event/command_succeeded_spec.rb +29 -7
  288. data/spec/mongo/monitoring_spec.rb +28 -3
  289. data/spec/mongo/protocol/get_more_spec.rb +2 -2
  290. data/spec/mongo/retryable_spec.rb +252 -34
  291. data/spec/mongo/retryable_writes_spec.rb +468 -544
  292. data/spec/mongo/server/connection_spec.rb +5 -5
  293. data/spec/mongo/server/description_spec.rb +23 -6
  294. data/spec/mongo/session/server_session_spec.rb +2 -2
  295. data/spec/mongo/session/session_pool_spec.rb +2 -2
  296. data/spec/mongo/transactions_examples_spec.rb +227 -0
  297. data/spec/mongo/transactions_spec.rb +44 -0
  298. data/spec/spec_helper.rb +135 -49
  299. data/spec/spec_tests/change_streams_spec.rb +42 -0
  300. data/spec/{mongo → spec_tests}/command_monitoring_spec.rb +8 -2
  301. data/spec/{mongo → spec_tests}/connection_string_spec.rb +1 -1
  302. data/spec/{mongo → spec_tests}/crud_spec.rb +5 -7
  303. data/spec/{mongo → spec_tests}/dns_seedlist_discovery_spec.rb +1 -1
  304. data/spec/{mongo → spec_tests}/gridfs_spec.rb +0 -0
  305. data/spec/{mongo → spec_tests}/max_staleness_spec.rb +0 -0
  306. data/spec/spec_tests/retryable_writes_spec.rb +78 -0
  307. data/spec/{mongo → spec_tests}/sdam_monitoring_spec.rb +4 -3
  308. data/spec/{mongo → spec_tests}/sdam_spec.rb +7 -7
  309. data/spec/{mongo → spec_tests}/server_selection_rtt_spec.rb +0 -0
  310. data/spec/{mongo → spec_tests}/server_selection_spec.rb +0 -0
  311. data/spec/support/authorization.rb +18 -6
  312. data/spec/support/change_streams.rb +265 -0
  313. data/spec/support/change_streams/operation.rb +62 -0
  314. data/spec/support/change_streams_tests/change-streams-errors.yml +53 -0
  315. data/spec/support/change_streams_tests/change-streams.yml +299 -0
  316. data/spec/support/command_monitoring.rb +1 -1
  317. data/spec/support/command_monitoring/bulkWrite.yml +4 -28
  318. data/spec/support/command_monitoring/command.yml +19 -0
  319. data/spec/support/command_monitoring/find.yml +17 -19
  320. data/spec/support/command_monitoring/insertMany.yml +2 -8
  321. data/spec/support/command_monitoring/unacknowledgedBulkWrite.yml +34 -0
  322. data/spec/support/connection_string.rb +1 -1
  323. data/spec/support/constraints.rb +56 -0
  324. data/spec/support/crud.rb +9 -4
  325. data/spec/support/crud/read.rb +24 -3
  326. data/spec/support/crud/write.rb +7 -2
  327. data/spec/support/crud_tests/read/count-collation.yml +12 -2
  328. data/spec/support/crud_tests/read/count.yml +43 -5
  329. data/spec/support/gridfs.rb +1 -1
  330. data/spec/support/primary_socket.rb +21 -0
  331. data/spec/support/retryable_writes_tests/bulkWrite-serverErrors.yml +90 -0
  332. data/spec/support/retryable_writes_tests/bulkWrite.yml +99 -1
  333. data/spec/support/retryable_writes_tests/deleteOne-serverErrors.yml +50 -0
  334. data/spec/support/retryable_writes_tests/deleteOne.yml +10 -1
  335. data/spec/support/retryable_writes_tests/findOneAndDelete-serverErrors.yml +50 -0
  336. data/spec/support/retryable_writes_tests/findOneAndDelete.yml +39 -30
  337. data/spec/support/retryable_writes_tests/findOneAndReplace-serverErrors.yml +54 -0
  338. data/spec/support/retryable_writes_tests/findOneAndReplace.yml +9 -0
  339. data/spec/support/retryable_writes_tests/findOneAndUpdate-serverErrors.yml +54 -0
  340. data/spec/support/retryable_writes_tests/findOneAndUpdate.yml +9 -0
  341. data/spec/support/retryable_writes_tests/insertMany-serverErrors.yml +59 -0
  342. data/spec/support/retryable_writes_tests/insertMany.yml +11 -6
  343. data/spec/support/retryable_writes_tests/insertOne-serverErrors.yml +471 -0
  344. data/spec/support/retryable_writes_tests/insertOne.yml +9 -0
  345. data/spec/support/retryable_writes_tests/replaceOne-serverErrors.yml +58 -0
  346. data/spec/support/retryable_writes_tests/replaceOne.yml +9 -0
  347. data/spec/support/retryable_writes_tests/updateOne-serverErrors.yml +58 -0
  348. data/spec/support/retryable_writes_tests/updateOne.yml +71 -53
  349. data/spec/support/sdam/rs/normalize_case_me.yml +100 -0
  350. data/spec/support/sdam/sharded/compatible.yml +38 -0
  351. data/spec/support/sdam/sharded/mongos_disconnect.yml +9 -3
  352. data/spec/support/sdam/sharded/multiple_mongoses.yml +6 -2
  353. data/spec/support/sdam/sharded/non_mongos_removed.yml +6 -2
  354. data/spec/support/sdam/sharded/too_new.yml +36 -0
  355. data/spec/support/sdam/sharded/too_old.yml +36 -0
  356. data/spec/support/sdam/single/compatible.yml +26 -0
  357. data/spec/support/sdam/single/direct_connection_external_ip.yml +3 -1
  358. data/spec/support/sdam/single/direct_connection_mongos.yml +3 -1
  359. data/spec/support/sdam/single/direct_connection_rsarbiter.yml +3 -1
  360. data/spec/support/sdam/single/direct_connection_rsprimary.yml +3 -1
  361. data/spec/support/sdam/single/direct_connection_rssecondary.yml +3 -1
  362. data/spec/support/sdam/single/direct_connection_slave.yml +3 -1
  363. data/spec/support/sdam/single/direct_connection_standalone.yml +3 -1
  364. data/spec/support/sdam/single/not_ok_response.yml +6 -2
  365. data/spec/support/sdam/single/standalone_removed.yml +3 -1
  366. data/spec/support/sdam/single/too_new.yml +26 -0
  367. data/spec/support/sdam/single/too_old.yml +24 -0
  368. data/spec/support/shared/session.rb +107 -0
  369. data/spec/support/transactions.rb +391 -0
  370. data/spec/support/transactions/operation.rb +373 -0
  371. data/spec/support/transactions_tests/abort.yml +403 -0
  372. data/spec/support/transactions_tests/bulk.yml +267 -0
  373. data/spec/support/transactions_tests/causal-consistency.yml +173 -0
  374. data/spec/support/transactions_tests/commit.yml +593 -0
  375. data/spec/support/transactions_tests/delete.yml +184 -0
  376. data/spec/support/transactions_tests/error-labels.yml +948 -0
  377. data/spec/support/transactions_tests/errors.yml +125 -0
  378. data/spec/support/transactions_tests/findOneAndDelete.yml +126 -0
  379. data/spec/support/transactions_tests/findOneAndReplace.yml +140 -0
  380. data/spec/support/transactions_tests/findOneAndUpdate.yml +228 -0
  381. data/spec/support/transactions_tests/insert.yml +264 -0
  382. data/spec/support/transactions_tests/isolation.yml +125 -0
  383. data/spec/support/transactions_tests/read-pref.yml +340 -0
  384. data/spec/support/transactions_tests/reads.yml +298 -0
  385. data/spec/support/transactions_tests/retryable-abort.yml +1292 -0
  386. data/spec/support/transactions_tests/retryable-commit.yml +1332 -0
  387. data/spec/support/transactions_tests/retryable-writes.yml +208 -0
  388. data/spec/support/transactions_tests/run-command.yml +189 -0
  389. data/spec/support/transactions_tests/transaction-options.yml +877 -0
  390. data/spec/support/transactions_tests/update.yml +246 -0
  391. data/spec/support/transactions_tests/write-concern.yml +236 -0
  392. metadata +494 -359
  393. metadata.gz.sig +0 -0
  394. data/lib/csasl/csasl.bundle +0 -0
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2017 MongoDB Inc.
1
+ # Copyright (C) 2014-2018 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -111,6 +111,10 @@ module Mongo
111
111
  @hashed_password ||= Digest::MD5.hexdigest("#{name}:mongo:#{password}").encode(BSON::UTF8)
112
112
  end
113
113
 
114
+ def sasl_prepped_hashed_password
115
+ @sasl_prepped_hashed_password ||= sasl_prepped_password.encode(BSON::UTF8)
116
+ end
117
+
114
118
  # Create the new user.
115
119
  #
116
120
  # @example Create a new user.
@@ -135,7 +139,7 @@ module Mongo
135
139
  @auth_source = options[:auth_source] || @database
136
140
  @name = options[:user]
137
141
  @password = options[:password] || options[:pwd]
138
- @mechanism = options[:auth_mech] || :mongodb_cr
142
+ @mechanism = options[:auth_mech]
139
143
  @auth_mech_properties = options[:auth_mech_properties] || {}
140
144
  @roles = options[:roles] || []
141
145
  @client_key = options[:client_key]
@@ -150,11 +154,18 @@ module Mongo
150
154
  #
151
155
  # @since 2.0.0
152
156
  def spec
153
- { pwd: hashed_password, roles: roles }
157
+ { pwd: password, roles: roles }
154
158
  end
155
159
 
156
160
  private
157
161
 
162
+ def sasl_prepped_password
163
+ StringPrep.prepare(password,
164
+ StringPrep::Profiles::SASL::MAPPINGS,
165
+ StringPrep::Profiles::SASL::PROHIBITED,
166
+ normalize: true, bidi: true)
167
+ end
168
+
158
169
  # The client key for the user.
159
170
  #
160
171
  # @return [ String ] The client key for the user.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2017 MongoDB, Inc.
1
+ # Copyright (C) 2014-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2017 MongoDB Inc.
1
+ # Copyright (C) 2014-2018 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014 MongoDB Inc.
1
+ # Copyright (C) 2014-2018 MongoDB Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2015-2017 MongoDB, Inc.
1
+ # Copyright (C) 2015-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2017 MongoDB, Inc.
1
+ # Copyright (C) 2014-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -168,19 +168,19 @@ module Mongo
168
168
  }
169
169
  end
170
170
 
171
- def execute_operation(name, values, server, operation_id, combiner, session, txn_num = nil)
171
+ def execute_operation(name, values, server, operation_id, result_combiner, session, txn_num = nil)
172
172
  raise Error::UnsupportedCollation.new if op_combiner.has_collation && !server.features.collation_enabled?
173
173
  raise Error::UnsupportedArrayFilters.new if op_combiner.has_array_filters && !server.features.array_filters_enabled?
174
174
  begin
175
175
  if values.size > server.max_write_batch_size
176
- split_execute(name, values, server, operation_id, combiner, session, txn_num)
176
+ split_execute(name, values, server, operation_id, result_combiner, session, txn_num)
177
177
  else
178
178
  result = send(name, values, server, operation_id, session, txn_num)
179
- combiner.combine!(result, values.size)
179
+ result_combiner.combine!(result, values.size)
180
180
  end
181
181
  rescue Error::MaxBSONSize, Error::MaxMessageSize => e
182
182
  raise e if values.size <= 1
183
- split_execute(name, values, server, operation_id, combiner, session, txn_num)
183
+ split_execute(name, values, server, operation_id, result_combiner, session, txn_num)
184
184
  end
185
185
  end
186
186
 
@@ -188,11 +188,11 @@ module Mongo
188
188
  @op_combiner ||= ordered? ? OrderedCombiner.new(requests) : UnorderedCombiner.new(requests)
189
189
  end
190
190
 
191
- def split_execute(name, values, server, operation_id, combiner, session, txn_num)
192
- execute_operation(name, values.shift(values.size / 2), server, operation_id, combiner, session, txn_num)
191
+ def split_execute(name, values, server, operation_id, result_combiner, session, txn_num)
192
+ execute_operation(name, values.shift(values.size / 2), server, operation_id, result_combiner, session, txn_num)
193
193
 
194
194
  txn_num = session.next_txn_num if txn_num
195
- execute_operation(name, values, server, operation_id, combiner, session, txn_num)
195
+ execute_operation(name, values, server, operation_id, result_combiner, session, txn_num)
196
196
  end
197
197
 
198
198
  def delete_one(documents, server, operation_id, session, txn_num)
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2015-2017 MongoDB, Inc.
1
+ # Copyright (C) 2015-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2015-2017 MongoDB, Inc.
1
+ # Copyright (C) 2015-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2015-2017 MongoDB, Inc.
1
+ # Copyright (C) 2015-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2015-2017 MongoDB, Inc.
1
+ # Copyright (C) 2015-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -22,7 +22,7 @@ module Mongo
22
22
  # @since 2.1.0
23
23
  class ResultCombiner
24
24
 
25
- # @return [ Integer ] count The count of documents in the entire batch.
25
+ # @return [ Integer ] count The number of documents in the entire batch.
26
26
  attr_reader :count
27
27
 
28
28
  # @return [ Hash ] results The results hash.
@@ -41,11 +41,11 @@ module Mongo
41
41
  @count = 0
42
42
  end
43
43
 
44
- # Combines a result into the overall results.
44
+ # Adds a result to the overall results.
45
45
  #
46
46
  # @api private
47
47
  #
48
- # @example Combine the result.
48
+ # @example Add the result.
49
49
  # combiner.combine!(result, count)
50
50
  #
51
51
  # @param [ Operation::Result ] result The result to combine.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2015-2017 MongoDB, Inc.
1
+ # Copyright (C) 2015-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2015-2017 MongoDB, Inc.
1
+ # Copyright (C) 2015-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2015-2017 MongoDB, Inc.
1
+ # Copyright (C) 2015-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2017 MongoDB, Inc.
1
+ # Copyright (C) 2014-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the 'License');
4
4
  # you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@ module Mongo
52
52
  :password,
53
53
  :platform,
54
54
  :read,
55
+ :read_concern,
55
56
  :read_retry_interval,
56
57
  :replica_set,
57
58
  :retry_writes,
@@ -94,7 +95,12 @@ module Mongo
94
95
  def_delegators :@database, :command, :collections
95
96
 
96
97
  # Delegate subscription to monitoring.
97
- def_delegators :@monitoring, :subscribe, :unsubscribe
98
+ def_delegators :monitoring, :subscribe, :unsubscribe
99
+
100
+ # Delegate monitoring to cluster.
101
+ def_delegators :cluster, :monitoring
102
+
103
+ private :monitoring
98
104
 
99
105
  # Determine if this client is equivalent to another object.
100
106
  #
@@ -142,17 +148,23 @@ module Mongo
142
148
  # Instantiate a new driver client.
143
149
  #
144
150
  # @example Instantiate a single server or mongos client.
145
- # Mongo::Client.new([ '127.0.0.1:27017' ])
151
+ # Mongo::Client.new(['127.0.0.1:27017'])
146
152
  #
147
153
  # @example Instantiate a client for a replica set.
148
- # Mongo::Client.new([ '127.0.0.1:27017', '127.0.0.1:27021' ])
154
+ # Mongo::Client.new(['127.0.0.1:27017', '127.0.0.1:27021'])
155
+ #
156
+ # @example Directly connect to a mongod in a replica set
157
+ # Mongo::Client.new(['127.0.0.1:27017'], :connect => :direct)
158
+ # # without `:connect => :direct`, Mongo::Client will discover and
159
+ # # connect to the replica set if given the address of a server in
160
+ # # a replica set
149
161
  #
150
162
  # @param [ Array<String>, String ] addresses_or_uri The array of server addresses in the
151
163
  # form of host:port or a MongoDB URI connection string.
152
164
  # @param [ Hash ] options The options to be used by the client.
153
165
  #
154
166
  # @option options [ Symbol ] :auth_mech The authentication mechanism to
155
- # use. One of :mongodb_cr, :mongodb_x509, :plain, :scram
167
+ # use. One of :mongodb_cr, :mongodb_x509, :plain, :scram, :scram256
156
168
  # @option options [ String ] :auth_source The source to authenticate from.
157
169
  # @option options [ Symbol ] :connect The connection method to use. This
158
170
  # forces the cluster to behave in the specified way instead of
@@ -177,13 +189,15 @@ module Mongo
177
189
  # @option options [ Float ] :connect_timeout The timeout, in seconds, to
178
190
  # attempt a connection.
179
191
  # @option options [ Array<String> ] :compressors A list of potential compressors to use, in order of preference.
180
- # The driver chooses the first compressor that is also supported by the server. Currently the driver only
192
+ # The driver chooses the first compressor that is also supported by the server. Currently the driver only
181
193
  # supports 'zlib'.
182
- # @option options [ Hash ] :read The read preference options. They consist of a
183
- # mode specified as a symbol, an array of hashes known as tag_sets,
184
- # and local_threshold.
185
- # :mode can be one of :secondary, :secondary_preferred, :primary,
186
- # :primary_preferred, :nearest.
194
+ # @option options [ Hash ] :read The read preference options. The hash
195
+ # may have the following items:
196
+ # - *:read* -- read preference specified as a symbol; valid values are
197
+ # *:primary*, *:primary_preferred*, *:secondary*, *:secondary_preferred*
198
+ # and *:nearest*.
199
+ # - *:tag_sets* -- an array of hashes.
200
+ # - *:local_threshold*.
187
201
  # @option options [ Symbol ] :replica_set The name of the replica set to
188
202
  # connect to. Servers not in this replica set will be ignored.
189
203
  # @option options [ true, false ] :ssl Whether to use SSL.
@@ -224,6 +238,7 @@ module Mongo
224
238
  # @option options [ String ] :user The user name.
225
239
  # @option options [ Hash ] :write The write concern options. Can be :w =>
226
240
  # Integer|String, :fsync => Boolean, :j => Boolean.
241
+ # @option options [ Hash ] :read_concern The read concern option.
227
242
  # @option options [ true, false ] :monitoring Initializes a client without
228
243
  # any default monitoring if false is provided.
229
244
  # @option options [ Logger ] :logger A custom logger if desired.
@@ -241,12 +256,11 @@ module Mongo
241
256
  # metadata printed to the mongod logs upon establishing a connection in server versions >= 3.4.
242
257
  # @option options [ Integer ] :zlib_compression_level The Zlib compression level to use, if using compression.
243
258
  # See Ruby's Zlib module for valid levels.
244
- # @option options [ true, false ] :retry_writes Retry writes once when connected to a replica set
245
- # or sharded cluster versions 3.6 and up.
259
+ # @option options [ true, false ] :retry_writes Retry writes once when
260
+ # connected to a replica set or sharded cluster versions 3.6 and up.
246
261
  #
247
262
  # @since 2.0.0
248
263
  def initialize(addresses_or_uri, options = Options::Redacted.new)
249
- @monitoring = Monitoring.new(options)
250
264
  if addresses_or_uri.is_a?(::String)
251
265
  create_from_uri(addresses_or_uri, validate_options!(options))
252
266
  else
@@ -267,14 +281,14 @@ module Mongo
267
281
  "#<Mongo::Client:0x#{object_id} cluster=#{cluster.addresses.join(', ')}>"
268
282
  end
269
283
 
270
- # Get the server selector. It either uses the read preference defined in the client options
271
- # or defaults to a Primary server selector.
284
+ # Get the server selector. It either uses the read preference
285
+ # defined in the client options or defaults to a Primary server selector.
272
286
  #
273
287
  # @example Get the server selector.
274
288
  # client.server_selector
275
289
  #
276
- # @return [ Mongo::ServerSelector ] The server selector using the user-defined read preference
277
- # or a Primary server selector default.
290
+ # @return [ Mongo::ServerSelector ] The server selector using the
291
+ # user-defined read preference or a Primary server selector default.
278
292
  #
279
293
  # @since 2.5.0
280
294
  def server_selector
@@ -333,6 +347,19 @@ module Mongo
333
347
  end
334
348
  end
335
349
 
350
+ # Get the read concern for this client.
351
+ #
352
+ # @example Get the client read concern.
353
+ # client.read_concern
354
+ #
355
+ # @return [ Hash ] The read concern.
356
+ #
357
+ # @since 2.6.0
358
+ def read_concern
359
+ @read_concern ||= options[:read_concern]
360
+ end
361
+
362
+
336
363
  # Get the write concern for this client. If no option was provided, then a
337
364
  # default single server acknowledgement will be used.
338
365
  #
@@ -435,36 +462,79 @@ module Mongo
435
462
  #
436
463
  # @since 2.5.0
437
464
  def start_session(options = {})
438
- cluster.send(:get_session, options.merge(implicit: false)) ||
465
+ cluster.send(:get_session, self, options.merge(implicit: false)) ||
439
466
  (raise Error::InvalidSession.new(Session::SESSIONS_NOT_SUPPORTED))
440
467
  end
441
468
 
469
+ # As of version 3.6 of the MongoDB server, a ``$changeStream`` pipeline stage is supported
470
+ # in the aggregation framework. As of version 4.0, this stage allows users to request that
471
+ # notifications are sent for all changes that occur in the client's cluster.
472
+ #
473
+ # @example Get change notifications for the client's cluster.
474
+ # client.watch([{ '$match' => { operationType: { '$in' => ['insert', 'replace'] } } }])
475
+ #
476
+ # @param [ Array<Hash> ] pipeline Optional additional filter operators.
477
+ # @param [ Hash ] options The change stream options.
478
+ #
479
+ # @option options [ String ] :full_document Allowed values: 'default', 'updateLookup'.
480
+ # Defaults to 'default'. When set to 'updateLookup', the change notification for partial
481
+ # updates will include both a delta describing the changes to the document, as well as a copy
482
+ # of the entire document that was changed from some time after the change occurred.
483
+ # @option options [ BSON::Document, Hash ] :resume_after Specifies the logical starting point
484
+ # for the new change stream.
485
+ # @option options [ Integer ] :max_await_time_ms The maximum amount of time for the server to
486
+ # wait on new documents to satisfy a change stream query.
487
+ # @option options [ Integer ] :batch_size The number of documents to return per batch.
488
+ # @option options [ BSON::Document, Hash ] :collation The collation to use.
489
+ # @option options [ Session ] :session The session to use.
490
+ # @option options [ BSON::Timestamp ] :start_at_operation_time Only return
491
+ # changes that occurred at or after the specified timestamp. Any command run
492
+ # against the server will return a cluster time that can be used here.
493
+ # Only recognized by server versions 4.0+.
494
+ #
495
+ # @note A change stream only allows 'majority' read concern.
496
+ # @note This helper method is preferable to running a raw aggregation with a $changeStream
497
+ # stage, for the purpose of supporting resumability.
498
+ #
499
+ # @return [ ChangeStream ] The change stream object.
500
+ #
501
+ # @since 2.6.0
502
+ def watch(pipeline = [], options = {})
503
+ return use(Database::ADMIN).watch(pipeline, options) unless database.name == Database::ADMIN
504
+
505
+ Mongo::Collection::View::ChangeStream.new(
506
+ Mongo::Collection::View.new(self["#{Database::COMMAND}.aggregate"]),
507
+ pipeline,
508
+ Mongo::Collection::View::ChangeStream::CLUSTER,
509
+ options)
510
+ end
511
+
442
512
  private
443
513
 
444
514
  def get_session(options = {})
445
- cluster.send(:get_session, options)
515
+ cluster.send(:get_session, self, options)
446
516
  end
447
517
 
448
518
  def with_session(options = {}, &block)
449
- cluster.send(:with_session, options, &block)
519
+ cluster.send(:with_session, self, options, &block)
450
520
  end
451
521
 
452
522
  def create_from_addresses(addresses, opts = Options::Redacted.new)
453
523
  @options = Database::DEFAULT_OPTIONS.merge(opts).freeze
454
- @cluster = Cluster.new(addresses, @monitoring, options)
524
+ @cluster = Cluster.new(addresses, Monitoring.new(options), options)
455
525
  @database = Database.new(self, options[:database], options)
456
526
  end
457
527
 
458
528
  def create_from_uri(connection_string, opts = Options::Redacted.new)
459
529
  uri = URI.get(connection_string, opts)
460
530
  @options = validate_options!(Database::DEFAULT_OPTIONS.merge(uri.client_options.merge(opts))).freeze
461
- @cluster = Cluster.new(uri.servers, @monitoring, options)
531
+ @cluster = Cluster.new(uri.servers, @cluster ? monitoring : Monitoring.new(options), options)
462
532
  @database = Database.new(self, options[:database], options)
463
533
  end
464
534
 
465
535
  def initialize_copy(original)
466
536
  @options = original.options.dup
467
- @monitoring = Monitoring.new(@options)
537
+ @monitoring = @cluster ? monitoring : Monitoring.new(options)
468
538
  @database = nil
469
539
  @read_preference = nil
470
540
  @write_concern = nil
@@ -485,6 +555,7 @@ module Mongo
485
555
  key = k.to_sym
486
556
  if VALID_OPTIONS.include?(key)
487
557
  validate_max_min_pool_size!(key, opts)
558
+ validate_read!(key, opts)
488
559
  if key == :compressors
489
560
  compressors = valid_compressors(v)
490
561
  _options[key] = compressors unless compressors.empty?
@@ -517,5 +588,25 @@ module Mongo
517
588
  end
518
589
  true
519
590
  end
591
+
592
+ def validate_read!(option, opts)
593
+ if option == :read && opts.has_key?(:read)
594
+ read = opts[:read]
595
+ # We could check if read is a Hash, but this would fail
596
+ # for custom classes implementing key access ([]).
597
+ # Instead reject common cases of strings and symbols.
598
+ if read.is_a?(String) || read.is_a?(Symbol)
599
+ raise Error::InvalidReadOption.new(read, 'must be a hash')
600
+ end
601
+
602
+ if mode = read[:mode]
603
+ mode = mode.to_sym
604
+ unless Mongo::ServerSelector::PREFERENCES.include?(mode)
605
+ raise Error::InvalidReadOption.new(read, "mode #{mode} is not one of recognized modes")
606
+ end
607
+ end
608
+ end
609
+ true
610
+ end
520
611
  end
521
612
  end
@@ -1,4 +1,4 @@
1
- # Copyright (C) 2014-2017 MongoDB, Inc.
1
+ # Copyright (C) 2014-2018 MongoDB, Inc.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -20,8 +20,8 @@ require 'mongo/cluster/app_metadata'
20
20
 
21
21
  module Mongo
22
22
 
23
- # Represents a group of servers on the server side, either as a single server, a
24
- # replica set, or a single or multiple mongos.
23
+ # Represents a group of servers on the server side, either as a
24
+ # single server, a replica set, or a single or multiple mongos.
25
25
  #
26
26
  # @since 2.0.0
27
27
  class Cluster
@@ -161,9 +161,16 @@ module Mongo
161
161
  #
162
162
  # @note Cluster should never be directly instantiated outside of a Client.
163
163
  #
164
- # @param [ Array<String> ] seeds The addresses of the configured servers.
164
+ # @note When connecting to a mongodb+srv:// URI, the client expands such a
165
+ # URI into a list of servers and passes that list to the Cluster
166
+ # constructor. When connecting to a standalone mongod, the Cluster
167
+ # constructor receives the corresponding address as an array of one string.
168
+ #
169
+ # @param [ Array<String> ] seeds The addresses of the configured servers
165
170
  # @param [ Monitoring ] monitoring The monitoring.
166
- # @param [ Hash ] options The options.
171
+ # @param [ Hash ] options Options. Client constructor forwards its
172
+ # options to Cluster constructor, although Cluster recognizes
173
+ # only a subset of the options recognized by Client.
167
174
  #
168
175
  # @since 2.0.0
169
176
  def initialize(seeds, monitoring, options = Options::Redacted.new)
@@ -448,7 +455,7 @@ module Mongo
448
455
  def self.create(client)
449
456
  cluster = Cluster.new(
450
457
  client.cluster.addresses.map(&:to_s),
451
- client.instance_variable_get(:@monitoring).dup,
458
+ Monitoring.new,
452
459
  client.options
453
460
  )
454
461
  client.instance_variable_set(:@cluster, cluster)
@@ -505,15 +512,15 @@ module Mongo
505
512
 
506
513
  private
507
514
 
508
- def get_session(options = {})
515
+ def get_session(client, options = {})
509
516
  return options[:session].validate!(self) if options[:session]
510
517
  if sessions_supported?
511
- Session.new(@session_pool.checkout, self, { implicit: true }.merge(options))
518
+ Session.new(@session_pool.checkout, client, { implicit: true }.merge(options))
512
519
  end
513
520
  end
514
521
 
515
- def with_session(options = {})
516
- session = get_session(options)
522
+ def with_session(client, options = {})
523
+ session = get_session(client, options)
517
524
  yield(session)
518
525
  ensure
519
526
  session.end_session if (session && session.implicit?)