mongo 2.23.0 → 2.24.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 (463) hide show
  1. checksums.yaml +4 -4
  2. data/bin/mongo_console +0 -1
  3. data/lib/mongo/active_support.rb +1 -2
  4. data/lib/mongo/address/ipv4.rb +3 -6
  5. data/lib/mongo/address/ipv6.rb +6 -10
  6. data/lib/mongo/address/unix.rb +1 -4
  7. data/lib/mongo/address/validator.rb +16 -28
  8. data/lib/mongo/address.rb +30 -40
  9. data/lib/mongo/auth/aws/conversation.rb +6 -10
  10. data/lib/mongo/auth/aws/credentials.rb +0 -1
  11. data/lib/mongo/auth/aws/credentials_cache.rb +0 -1
  12. data/lib/mongo/auth/aws/credentials_retriever.rb +45 -59
  13. data/lib/mongo/auth/aws/request.rb +20 -35
  14. data/lib/mongo/auth/aws.rb +1 -2
  15. data/lib/mongo/auth/base.rb +20 -29
  16. data/lib/mongo/auth/conversation_base.rb +14 -18
  17. data/lib/mongo/auth/cr/conversation.rb +0 -3
  18. data/lib/mongo/auth/cr.rb +1 -4
  19. data/lib/mongo/auth/credential_cache.rb +0 -2
  20. data/lib/mongo/auth/gssapi/conversation.rb +3 -8
  21. data/lib/mongo/auth/gssapi.rb +1 -4
  22. data/lib/mongo/auth/ldap/conversation.rb +0 -3
  23. data/lib/mongo/auth/ldap.rb +1 -4
  24. data/lib/mongo/auth/roles.rb +16 -19
  25. data/lib/mongo/auth/sasl_conversation_base.rb +7 -11
  26. data/lib/mongo/auth/scram/conversation.rb +2 -5
  27. data/lib/mongo/auth/scram.rb +5 -10
  28. data/lib/mongo/auth/scram256/conversation.rb +2 -5
  29. data/lib/mongo/auth/scram256.rb +1 -3
  30. data/lib/mongo/auth/scram_conversation_base.rb +18 -24
  31. data/lib/mongo/auth/stringprep/profiles/sasl.rb +17 -18
  32. data/lib/mongo/auth/stringprep/tables.rb +2209 -2210
  33. data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +36 -38
  34. data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +1142 -1150
  35. data/lib/mongo/auth/stringprep.rb +9 -12
  36. data/lib/mongo/auth/user/view.rb +3 -5
  37. data/lib/mongo/auth/user.rb +14 -24
  38. data/lib/mongo/auth/x509/conversation.rb +0 -3
  39. data/lib/mongo/auth/x509.rb +7 -9
  40. data/lib/mongo/auth.rb +18 -30
  41. data/lib/mongo/background_thread.rb +9 -17
  42. data/lib/mongo/bson.rb +0 -2
  43. data/lib/mongo/bulk_write/combineable.rb +0 -3
  44. data/lib/mongo/bulk_write/ordered_combiner.rb +1 -3
  45. data/lib/mongo/bulk_write/result.rb +11 -16
  46. data/lib/mongo/bulk_write/result_combiner.rb +9 -12
  47. data/lib/mongo/bulk_write/transformable.rb +16 -19
  48. data/lib/mongo/bulk_write/unordered_combiner.rb +1 -3
  49. data/lib/mongo/bulk_write/validatable.rb +11 -18
  50. data/lib/mongo/bulk_write.rb +76 -91
  51. data/lib/mongo/caching_cursor.rb +2 -7
  52. data/lib/mongo/client.rb +230 -275
  53. data/lib/mongo/client_encryption.rb +4 -5
  54. data/lib/mongo/cluster/periodic_executor.rb +2 -5
  55. data/lib/mongo/cluster/reapers/cursor_reaper.rb +21 -29
  56. data/lib/mongo/cluster/reapers/socket_reaper.rb +1 -6
  57. data/lib/mongo/cluster/sdam_flow.rb +136 -159
  58. data/lib/mongo/cluster/topology/base.rb +15 -18
  59. data/lib/mongo/cluster/topology/load_balanced.rb +24 -14
  60. data/lib/mongo/cluster/topology/no_replica_set_options.rb +3 -6
  61. data/lib/mongo/cluster/topology/replica_set_no_primary.rb +20 -23
  62. data/lib/mongo/cluster/topology/replica_set_with_primary.rb +0 -2
  63. data/lib/mongo/cluster/topology/sharded.rb +19 -9
  64. data/lib/mongo/cluster/topology/single.rb +24 -14
  65. data/lib/mongo/cluster/topology/unknown.rb +20 -10
  66. data/lib/mongo/cluster/topology.rb +29 -25
  67. data/lib/mongo/cluster.rb +148 -183
  68. data/lib/mongo/cluster_time.rb +14 -31
  69. data/lib/mongo/collection/helpers.rb +5 -8
  70. data/lib/mongo/collection/view/aggregation.rb +5 -10
  71. data/lib/mongo/collection/view/builder/aggregation.rb +6 -9
  72. data/lib/mongo/collection/view/builder/map_reduce.rb +18 -17
  73. data/lib/mongo/collection/view/builder.rb +0 -1
  74. data/lib/mongo/collection/view/change_stream/retryable.rb +3 -8
  75. data/lib/mongo/collection/view/change_stream.rb +59 -58
  76. data/lib/mongo/collection/view/explainable.rb +11 -20
  77. data/lib/mongo/collection/view/immutable.rb +1 -3
  78. data/lib/mongo/collection/view/iterable.rb +35 -28
  79. data/lib/mongo/collection/view/map_reduce.rb +20 -25
  80. data/lib/mongo/collection/view/readable.rb +50 -57
  81. data/lib/mongo/collection/view/writable.rb +56 -72
  82. data/lib/mongo/collection/view.rb +9 -8
  83. data/lib/mongo/collection.rb +63 -76
  84. data/lib/mongo/condition_variable.rb +4 -4
  85. data/lib/mongo/config/options.rb +0 -3
  86. data/lib/mongo/config/validators/option.rb +3 -5
  87. data/lib/mongo/config.rb +2 -4
  88. data/lib/mongo/crypt/auto_decryption_context.rb +0 -3
  89. data/lib/mongo/crypt/auto_encrypter.rb +34 -43
  90. data/lib/mongo/crypt/auto_encryption_context.rb +0 -3
  91. data/lib/mongo/crypt/binary.rb +5 -9
  92. data/lib/mongo/crypt/binding.rb +149 -155
  93. data/lib/mongo/crypt/context.rb +10 -17
  94. data/lib/mongo/crypt/data_key_context.rb +2 -7
  95. data/lib/mongo/crypt/encryption_io.rb +29 -39
  96. data/lib/mongo/crypt/explicit_decryption_context.rb +0 -3
  97. data/lib/mongo/crypt/explicit_encrypter.rb +1 -1
  98. data/lib/mongo/crypt/explicit_encryption_context.rb +19 -30
  99. data/lib/mongo/crypt/explicit_encryption_expression_context.rb +0 -2
  100. data/lib/mongo/crypt/handle.rb +42 -48
  101. data/lib/mongo/crypt/hooks.rb +12 -15
  102. data/lib/mongo/crypt/kms/aws/credentials.rb +12 -16
  103. data/lib/mongo/crypt/kms/aws/master_document.rb +6 -9
  104. data/lib/mongo/crypt/kms/aws.rb +0 -2
  105. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +2 -7
  106. data/lib/mongo/crypt/kms/azure/master_document.rb +15 -19
  107. data/lib/mongo/crypt/kms/azure.rb +0 -1
  108. data/lib/mongo/crypt/kms/credentials.rb +13 -27
  109. data/lib/mongo/crypt/kms/gcp/credentials.rb +12 -14
  110. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +7 -9
  111. data/lib/mongo/crypt/kms/gcp/master_document.rb +12 -16
  112. data/lib/mongo/crypt/kms/gcp.rb +0 -2
  113. data/lib/mongo/crypt/kms/kmip/credentials.rb +7 -8
  114. data/lib/mongo/crypt/kms/kmip/master_document.rb +3 -5
  115. data/lib/mongo/crypt/kms/kmip.rb +0 -1
  116. data/lib/mongo/crypt/kms/local/credentials.rb +7 -8
  117. data/lib/mongo/crypt/kms/local/master_document.rb +2 -6
  118. data/lib/mongo/crypt/kms/local.rb +0 -1
  119. data/lib/mongo/crypt/kms/master_key_document.rb +11 -15
  120. data/lib/mongo/crypt/kms.rb +14 -16
  121. data/lib/mongo/crypt/kms_context.rb +0 -2
  122. data/lib/mongo/crypt/rewrap_many_data_key_context.rb +2 -7
  123. data/lib/mongo/crypt/rewrap_many_data_key_result.rb +2 -4
  124. data/lib/mongo/crypt/status.rb +12 -14
  125. data/lib/mongo/crypt.rb +0 -1
  126. data/lib/mongo/csot_timeout_holder.rb +3 -2
  127. data/lib/mongo/cursor/kill_spec.rb +7 -10
  128. data/lib/mongo/cursor.rb +74 -64
  129. data/lib/mongo/cursor_host.rb +8 -10
  130. data/lib/mongo/database/view.rb +16 -37
  131. data/lib/mongo/database.rb +52 -56
  132. data/lib/mongo/dbref.rb +0 -1
  133. data/lib/mongo/distinguishing_semaphore.rb +0 -1
  134. data/lib/mongo/error/auth_error.rb +0 -2
  135. data/lib/mongo/error/bad_load_balancer_target.rb +0 -2
  136. data/lib/mongo/error/bulk_write_error.rb +7 -10
  137. data/lib/mongo/error/change_stream_resumable.rb +0 -2
  138. data/lib/mongo/error/client_closed.rb +0 -2
  139. data/lib/mongo/error/closed_stream.rb +1 -4
  140. data/lib/mongo/error/connection_check_out_timeout.rb +3 -6
  141. data/lib/mongo/error/connection_perished.rb +0 -2
  142. data/lib/mongo/error/connection_unavailable.rb +0 -2
  143. data/lib/mongo/error/credential_check_error.rb +0 -2
  144. data/lib/mongo/error/crypt_error.rb +0 -2
  145. data/lib/mongo/error/extra_file_chunk.rb +1 -4
  146. data/lib/mongo/error/failed_string_prep_validation.rb +5 -6
  147. data/lib/mongo/error/file_not_found.rb +0 -3
  148. data/lib/mongo/error/handshake_error.rb +0 -2
  149. data/lib/mongo/error/insufficient_iteration_count.rb +1 -4
  150. data/lib/mongo/error/internal_driver_error.rb +0 -2
  151. data/lib/mongo/error/invalid_address.rb +0 -2
  152. data/lib/mongo/error/invalid_application_name.rb +0 -3
  153. data/lib/mongo/error/invalid_bulk_operation.rb +1 -4
  154. data/lib/mongo/error/invalid_bulk_operation_type.rb +1 -4
  155. data/lib/mongo/error/invalid_collection_name.rb +1 -4
  156. data/lib/mongo/error/invalid_config_option.rb +0 -3
  157. data/lib/mongo/error/invalid_cursor_operation.rb +0 -2
  158. data/lib/mongo/error/invalid_database_name.rb +1 -4
  159. data/lib/mongo/error/invalid_document.rb +1 -4
  160. data/lib/mongo/error/invalid_file.rb +0 -3
  161. data/lib/mongo/error/invalid_file_revision.rb +0 -3
  162. data/lib/mongo/error/invalid_min_pool_size.rb +0 -3
  163. data/lib/mongo/error/invalid_nonce.rb +0 -3
  164. data/lib/mongo/error/invalid_read_concern.rb +2 -4
  165. data/lib/mongo/error/invalid_read_option.rb +0 -3
  166. data/lib/mongo/error/invalid_replacement_document.rb +2 -5
  167. data/lib/mongo/error/invalid_server_auth_host.rb +0 -2
  168. data/lib/mongo/error/invalid_server_auth_response.rb +0 -2
  169. data/lib/mongo/error/invalid_server_preference.rb +7 -16
  170. data/lib/mongo/error/invalid_session.rb +1 -4
  171. data/lib/mongo/error/invalid_signature.rb +0 -3
  172. data/lib/mongo/error/invalid_transaction_operation.rb +5 -8
  173. data/lib/mongo/error/invalid_txt_record.rb +0 -2
  174. data/lib/mongo/error/invalid_update_document.rb +2 -5
  175. data/lib/mongo/error/invalid_uri.rb +1 -4
  176. data/lib/mongo/error/invalid_write_concern.rb +2 -5
  177. data/lib/mongo/error/kms_error.rb +0 -2
  178. data/lib/mongo/error/labelable.rb +0 -3
  179. data/lib/mongo/error/lint_error.rb +0 -2
  180. data/lib/mongo/error/max_bson_size.rb +8 -11
  181. data/lib/mongo/error/max_message_size.rb +2 -5
  182. data/lib/mongo/error/mismatched_domain.rb +0 -2
  183. data/lib/mongo/error/missing_connection.rb +0 -2
  184. data/lib/mongo/error/missing_file_chunk.rb +0 -3
  185. data/lib/mongo/error/missing_password.rb +0 -2
  186. data/lib/mongo/error/missing_resume_token.rb +1 -4
  187. data/lib/mongo/error/missing_scram_server_signature.rb +2 -4
  188. data/lib/mongo/error/missing_service_id.rb +0 -2
  189. data/lib/mongo/error/mongocryptd_spawn_error.rb +0 -2
  190. data/lib/mongo/error/multi_index_drop.rb +0 -3
  191. data/lib/mongo/error/need_primary_server.rb +0 -2
  192. data/lib/mongo/error/no_server_available.rb +3 -8
  193. data/lib/mongo/error/no_service_connection_available.rb +1 -3
  194. data/lib/mongo/error/no_srv_records.rb +0 -2
  195. data/lib/mongo/error/notable.rb +8 -16
  196. data/lib/mongo/error/operation_failure.rb +22 -35
  197. data/lib/mongo/error/parser.rb +33 -75
  198. data/lib/mongo/error/pool_cleared_error.rb +1 -3
  199. data/lib/mongo/error/pool_closed_error.rb +0 -3
  200. data/lib/mongo/error/pool_error.rb +0 -3
  201. data/lib/mongo/error/pool_paused_error.rb +0 -2
  202. data/lib/mongo/error/raise_original_error.rb +1 -3
  203. data/lib/mongo/error/read_write_retryable.rb +14 -17
  204. data/lib/mongo/error/sdam_error_detection.rb +3 -5
  205. data/lib/mongo/error/server_api_conflict.rb +0 -2
  206. data/lib/mongo/error/server_certificate_revoked.rb +0 -2
  207. data/lib/mongo/error/server_not_usable.rb +0 -2
  208. data/lib/mongo/error/session_ended.rb +1 -3
  209. data/lib/mongo/error/session_not_materialized.rb +1 -3
  210. data/lib/mongo/error/sessions_not_supported.rb +1 -4
  211. data/lib/mongo/error/snapshot_session_invalid_server_version.rb +1 -4
  212. data/lib/mongo/error/snapshot_session_transaction_prohibited.rb +1 -4
  213. data/lib/mongo/error/socket_error.rb +0 -2
  214. data/lib/mongo/error/socket_timeout_error.rb +0 -2
  215. data/lib/mongo/error/transactions_not_supported.rb +3 -6
  216. data/lib/mongo/error/unchangeable_collection_option.rb +1 -4
  217. data/lib/mongo/error/unexpected_chunk_length.rb +0 -3
  218. data/lib/mongo/error/unexpected_response.rb +1 -4
  219. data/lib/mongo/error/unknown_payload_type.rb +0 -3
  220. data/lib/mongo/error/unmet_dependency.rb +0 -2
  221. data/lib/mongo/error/unsupported_array_filters.rb +3 -24
  222. data/lib/mongo/error/unsupported_collation.rb +3 -24
  223. data/lib/mongo/error/unsupported_features.rb +0 -2
  224. data/lib/mongo/error/unsupported_message_type.rb +0 -2
  225. data/lib/mongo/error/unsupported_option.rb +19 -21
  226. data/lib/mongo/error/write_retryable.rb +0 -2
  227. data/lib/mongo/error.rb +10 -24
  228. data/lib/mongo/event/base.rb +0 -2
  229. data/lib/mongo/event/listeners.rb +0 -3
  230. data/lib/mongo/event/publisher.rb +0 -3
  231. data/lib/mongo/event/subscriber.rb +0 -4
  232. data/lib/mongo/event.rb +4 -6
  233. data/lib/mongo/grid/file/chunk.rb +7 -10
  234. data/lib/mongo/grid/file/info.rb +20 -24
  235. data/lib/mongo/grid/file.rb +7 -8
  236. data/lib/mongo/grid/fs_bucket.rb +40 -48
  237. data/lib/mongo/grid/stream/read.rb +25 -35
  238. data/lib/mongo/grid/stream/write.rb +17 -22
  239. data/lib/mongo/grid/stream.rb +2 -4
  240. data/lib/mongo/grid.rb +0 -1
  241. data/lib/mongo/id.rb +0 -1
  242. data/lib/mongo/index/view.rb +49 -48
  243. data/lib/mongo/index.rb +7 -10
  244. data/lib/mongo/lint.rb +31 -37
  245. data/lib/mongo/loggable.rb +5 -8
  246. data/lib/mongo/logger.rb +1 -7
  247. data/lib/mongo/monitoring/cmap_log_subscriber.rb +0 -2
  248. data/lib/mongo/monitoring/command_log_subscriber.rb +25 -33
  249. data/lib/mongo/monitoring/event/cmap/base.rb +0 -2
  250. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -4
  251. data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +0 -3
  252. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +1 -4
  253. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +2 -5
  254. data/lib/mongo/monitoring/event/cmap/connection_closed.rb +1 -4
  255. data/lib/mongo/monitoring/event/cmap/connection_created.rb +1 -4
  256. data/lib/mongo/monitoring/event/cmap/connection_ready.rb +1 -4
  257. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +0 -3
  258. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +1 -4
  259. data/lib/mongo/monitoring/event/cmap/pool_created.rb +1 -4
  260. data/lib/mongo/monitoring/event/cmap/pool_ready.rb +1 -4
  261. data/lib/mongo/monitoring/event/cmap.rb +0 -1
  262. data/lib/mongo/monitoring/event/command_failed.rb +5 -9
  263. data/lib/mongo/monitoring/event/command_started.rb +8 -12
  264. data/lib/mongo/monitoring/event/command_succeeded.rb +7 -15
  265. data/lib/mongo/monitoring/event/secure.rb +15 -20
  266. data/lib/mongo/monitoring/event/server_closed.rb +1 -4
  267. data/lib/mongo/monitoring/event/server_description_changed.rb +4 -8
  268. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +5 -10
  269. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +1 -4
  270. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +3 -8
  271. data/lib/mongo/monitoring/event/server_opening.rb +1 -4
  272. data/lib/mongo/monitoring/event/topology_changed.rb +2 -5
  273. data/lib/mongo/monitoring/event/topology_closed.rb +1 -4
  274. data/lib/mongo/monitoring/event/topology_opening.rb +1 -4
  275. data/lib/mongo/monitoring/event.rb +0 -1
  276. data/lib/mongo/monitoring/publishable.rb +20 -30
  277. data/lib/mongo/monitoring/sdam_log_subscriber.rb +0 -2
  278. data/lib/mongo/monitoring/server_closed_log_subscriber.rb +0 -3
  279. data/lib/mongo/monitoring/server_description_changed_log_subscriber.rb +0 -3
  280. data/lib/mongo/monitoring/server_opening_log_subscriber.rb +0 -3
  281. data/lib/mongo/monitoring/topology_changed_log_subscriber.rb +5 -8
  282. data/lib/mongo/monitoring/topology_closed_log_subscriber.rb +0 -3
  283. data/lib/mongo/monitoring/topology_opening_log_subscriber.rb +0 -3
  284. data/lib/mongo/monitoring/unified_sdam_log_subscriber.rb +1 -3
  285. data/lib/mongo/monitoring.rb +38 -39
  286. data/lib/mongo/operation/aggregate/op_msg.rb +0 -2
  287. data/lib/mongo/operation/aggregate/result.rb +3 -6
  288. data/lib/mongo/operation/aggregate.rb +0 -2
  289. data/lib/mongo/operation/collections_info/result.rb +0 -3
  290. data/lib/mongo/operation/collections_info.rb +0 -2
  291. data/lib/mongo/operation/command/op_msg.rb +1 -4
  292. data/lib/mongo/operation/command.rb +0 -2
  293. data/lib/mongo/operation/context.rb +13 -16
  294. data/lib/mongo/operation/count/op_msg.rb +2 -4
  295. data/lib/mongo/operation/count.rb +0 -2
  296. data/lib/mongo/operation/create/op_msg.rb +2 -5
  297. data/lib/mongo/operation/create.rb +0 -2
  298. data/lib/mongo/operation/create_index/op_msg.rb +3 -7
  299. data/lib/mongo/operation/create_index.rb +0 -2
  300. data/lib/mongo/operation/create_user/op_msg.rb +2 -4
  301. data/lib/mongo/operation/create_user.rb +0 -2
  302. data/lib/mongo/operation/delete/bulk_result.rb +2 -3
  303. data/lib/mongo/operation/delete/op_msg.rb +3 -10
  304. data/lib/mongo/operation/delete/result.rb +0 -3
  305. data/lib/mongo/operation/delete.rb +1 -5
  306. data/lib/mongo/operation/distinct/op_msg.rb +2 -5
  307. data/lib/mongo/operation/distinct.rb +0 -2
  308. data/lib/mongo/operation/drop/op_msg.rb +0 -2
  309. data/lib/mongo/operation/drop.rb +0 -2
  310. data/lib/mongo/operation/drop_database/op_msg.rb +0 -2
  311. data/lib/mongo/operation/drop_database.rb +0 -2
  312. data/lib/mongo/operation/drop_index/op_msg.rb +4 -6
  313. data/lib/mongo/operation/drop_index.rb +0 -2
  314. data/lib/mongo/operation/explain/op_msg.rb +0 -2
  315. data/lib/mongo/operation/explain/result.rb +0 -3
  316. data/lib/mongo/operation/explain.rb +0 -2
  317. data/lib/mongo/operation/find/builder/command.rb +4 -12
  318. data/lib/mongo/operation/find/builder/flags.rb +9 -15
  319. data/lib/mongo/operation/find/builder/modifiers.rb +1 -4
  320. data/lib/mongo/operation/find/builder.rb +0 -1
  321. data/lib/mongo/operation/find/op_msg.rb +4 -12
  322. data/lib/mongo/operation/find/result.rb +0 -3
  323. data/lib/mongo/operation/find.rb +0 -2
  324. data/lib/mongo/operation/get_more/command_builder.rb +1 -6
  325. data/lib/mongo/operation/get_more/op_msg.rb +10 -4
  326. data/lib/mongo/operation/get_more/result.rb +0 -3
  327. data/lib/mongo/operation/get_more.rb +0 -2
  328. data/lib/mongo/operation/indexes/op_msg.rb +0 -2
  329. data/lib/mongo/operation/indexes/result.rb +1 -5
  330. data/lib/mongo/operation/indexes.rb +0 -2
  331. data/lib/mongo/operation/insert/bulk_result.rb +2 -6
  332. data/lib/mongo/operation/insert/op_msg.rb +2 -4
  333. data/lib/mongo/operation/insert/result.rb +0 -3
  334. data/lib/mongo/operation/insert.rb +2 -5
  335. data/lib/mongo/operation/kill_cursors/command_builder.rb +0 -3
  336. data/lib/mongo/operation/kill_cursors/op_msg.rb +1 -3
  337. data/lib/mongo/operation/kill_cursors.rb +0 -2
  338. data/lib/mongo/operation/list_collections/op_msg.rb +4 -6
  339. data/lib/mongo/operation/list_collections/result.rb +1 -4
  340. data/lib/mongo/operation/list_collections.rb +0 -2
  341. data/lib/mongo/operation/map_reduce/op_msg.rb +0 -2
  342. data/lib/mongo/operation/map_reduce/result.rb +3 -6
  343. data/lib/mongo/operation/map_reduce.rb +0 -2
  344. data/lib/mongo/operation/op_msg_base.rb +0 -1
  345. data/lib/mongo/operation/parallel_scan/op_msg.rb +4 -5
  346. data/lib/mongo/operation/parallel_scan/result.rb +2 -5
  347. data/lib/mongo/operation/parallel_scan.rb +0 -2
  348. data/lib/mongo/operation/remove_user/op_msg.rb +2 -4
  349. data/lib/mongo/operation/remove_user.rb +0 -2
  350. data/lib/mongo/operation/result.rb +38 -48
  351. data/lib/mongo/operation/shared/bypass_document_validation.rb +3 -7
  352. data/lib/mongo/operation/shared/causal_consistency_supported.rb +0 -3
  353. data/lib/mongo/operation/shared/executable.rb +19 -28
  354. data/lib/mongo/operation/shared/executable_no_validate.rb +0 -3
  355. data/lib/mongo/operation/shared/executable_transaction_label.rb +0 -2
  356. data/lib/mongo/operation/shared/idable.rb +3 -6
  357. data/lib/mongo/operation/shared/limited.rb +0 -3
  358. data/lib/mongo/operation/shared/object_id_generator.rb +0 -3
  359. data/lib/mongo/operation/shared/op_msg_executable.rb +0 -2
  360. data/lib/mongo/operation/shared/polymorphic_lookup.rb +0 -2
  361. data/lib/mongo/operation/shared/polymorphic_result.rb +2 -4
  362. data/lib/mongo/operation/shared/read_preference_supported.rb +10 -15
  363. data/lib/mongo/operation/shared/response_handling.rb +13 -26
  364. data/lib/mongo/operation/shared/result/aggregatable.rb +12 -13
  365. data/lib/mongo/operation/shared/sessions_supported.rb +87 -99
  366. data/lib/mongo/operation/shared/specifiable.rb +32 -58
  367. data/lib/mongo/operation/shared/write.rb +12 -17
  368. data/lib/mongo/operation/shared/write_concern_supported.rb +4 -7
  369. data/lib/mongo/operation/update/bulk_result.rb +13 -17
  370. data/lib/mongo/operation/update/op_msg.rb +2 -5
  371. data/lib/mongo/operation/update/result.rb +5 -5
  372. data/lib/mongo/operation/update.rb +1 -5
  373. data/lib/mongo/operation/update_user/op_msg.rb +2 -4
  374. data/lib/mongo/operation/update_user.rb +0 -2
  375. data/lib/mongo/operation/users_info/op_msg.rb +2 -4
  376. data/lib/mongo/operation/users_info/result.rb +1 -4
  377. data/lib/mongo/operation/users_info.rb +0 -2
  378. data/lib/mongo/operation/write_command/op_msg.rb +2 -10
  379. data/lib/mongo/operation/write_command.rb +0 -2
  380. data/lib/mongo/operation.rb +9 -14
  381. data/lib/mongo/options/mapper.rb +8 -15
  382. data/lib/mongo/options/redacted.rb +7 -9
  383. data/lib/mongo/options.rb +0 -1
  384. data/lib/mongo/protocol/bit_vector.rb +3 -5
  385. data/lib/mongo/protocol/caching_hash.rb +2 -7
  386. data/lib/mongo/protocol/compressed.rb +5 -10
  387. data/lib/mongo/protocol/get_more.rb +2 -8
  388. data/lib/mongo/protocol/kill_cursors.rb +2 -8
  389. data/lib/mongo/protocol/message.rb +103 -105
  390. data/lib/mongo/protocol/msg.rb +48 -63
  391. data/lib/mongo/protocol/query.rb +32 -41
  392. data/lib/mongo/protocol/registry.rb +2 -5
  393. data/lib/mongo/protocol/reply.rb +10 -16
  394. data/lib/mongo/protocol/serializers.rb +41 -59
  395. data/lib/mongo/protocol.rb +0 -1
  396. data/lib/mongo/query_cache.rb +7 -15
  397. data/lib/mongo/retryable/backpressure.rb +31 -0
  398. data/lib/mongo/retryable/base_worker.rb +39 -13
  399. data/lib/mongo/retryable/read_worker.rb +77 -21
  400. data/lib/mongo/retryable/retry_policy.rb +59 -0
  401. data/lib/mongo/retryable/write_worker.rb +155 -56
  402. data/lib/mongo/retryable.rb +70 -9
  403. data/lib/mongo/search_index/view.rb +1 -1
  404. data/lib/mongo/semaphore.rb +0 -1
  405. data/lib/mongo/server/app_metadata/environment.rb +3 -3
  406. data/lib/mongo/server/app_metadata.rb +4 -5
  407. data/lib/mongo/server/connection.rb +61 -61
  408. data/lib/mongo/server/connection_base.rb +43 -53
  409. data/lib/mongo/server/connection_common.rb +41 -64
  410. data/lib/mongo/server/connection_pool/generation_manager.rb +6 -11
  411. data/lib/mongo/server/connection_pool/populator.rb +1 -4
  412. data/lib/mongo/server/connection_pool.rb +195 -167
  413. data/lib/mongo/server/description/features.rb +23 -60
  414. data/lib/mongo/server/description/load_balancer.rb +0 -2
  415. data/lib/mongo/server/description.rb +117 -138
  416. data/lib/mongo/server/monitor/app_metadata.rb +3 -4
  417. data/lib/mongo/server/monitor/connection.rb +28 -35
  418. data/lib/mongo/server/monitor.rb +65 -60
  419. data/lib/mongo/server/pending_connection.rb +70 -71
  420. data/lib/mongo/server/push_monitor/connection.rb +0 -3
  421. data/lib/mongo/server/push_monitor.rb +21 -29
  422. data/lib/mongo/server/round_trip_time_calculator.rb +11 -17
  423. data/lib/mongo/server.rb +60 -93
  424. data/lib/mongo/server_selector/base.rb +133 -157
  425. data/lib/mongo/server_selector/nearest.rb +2 -5
  426. data/lib/mongo/server_selector/primary.rb +1 -5
  427. data/lib/mongo/server_selector/primary_preferred.rb +2 -6
  428. data/lib/mongo/server_selector/secondary.rb +2 -6
  429. data/lib/mongo/server_selector/secondary_preferred.rb +1 -5
  430. data/lib/mongo/server_selector.rb +3 -4
  431. data/lib/mongo/session/server_session.rb +6 -7
  432. data/lib/mongo/session/session_pool.rb +20 -34
  433. data/lib/mongo/session.rb +287 -188
  434. data/lib/mongo/socket/ocsp_cache.rb +8 -13
  435. data/lib/mongo/socket/ocsp_verifier.rb +69 -70
  436. data/lib/mongo/socket/ssl.rb +44 -43
  437. data/lib/mongo/socket/tcp.rb +5 -8
  438. data/lib/mongo/socket/unix.rb +0 -4
  439. data/lib/mongo/socket.rb +80 -102
  440. data/lib/mongo/srv/monitor.rb +6 -11
  441. data/lib/mongo/srv/resolver.rb +15 -24
  442. data/lib/mongo/srv/result.rb +18 -24
  443. data/lib/mongo/srv.rb +0 -1
  444. data/lib/mongo/timeout.rb +4 -11
  445. data/lib/mongo/topology_version.rb +8 -13
  446. data/lib/mongo/tracing/open_telemetry/command_tracer.rb +1 -1
  447. data/lib/mongo/tracing/open_telemetry/operation_tracer.rb +1 -1
  448. data/lib/mongo/tracing/open_telemetry/tracer.rb +1 -1
  449. data/lib/mongo/uri/options_mapper.rb +135 -126
  450. data/lib/mongo/uri/srv_protocol.rb +25 -38
  451. data/lib/mongo/uri.rb +95 -139
  452. data/lib/mongo/utils.rb +5 -12
  453. data/lib/mongo/version.rb +1 -1
  454. data/lib/mongo/write_concern/acknowledged.rb +0 -2
  455. data/lib/mongo/write_concern/base.rb +6 -6
  456. data/lib/mongo/write_concern/unacknowledged.rb +0 -2
  457. data/lib/mongo/write_concern.rb +14 -15
  458. data/lib/mongo.rb +1 -3
  459. data/mongo.gemspec +17 -17
  460. metadata +5 -5
  461. data/lib/mongo/error/server_api_not_supported.rb +0 -27
  462. data/lib/mongo/operation/shared/result/use_legacy_error_parser.rb +0 -32
  463. data/lib/mongo/operation/shared/validatable.rb +0 -87
data/lib/mongo/client.rb CHANGED
@@ -1,5 +1,4 @@
1
1
  # frozen_string_literal: true
2
- # rubocop:todo all
3
2
 
4
3
  # Copyright (C) 2014-2020 MongoDB Inc.
5
4
  #
@@ -16,7 +15,6 @@
16
15
  # limitations under the License.
17
16
 
18
17
  module Mongo
19
-
20
18
  # The client is the entry point to the driver and is the main object that
21
19
  # will be interacted with.
22
20
  #
@@ -36,6 +34,8 @@ module Mongo
36
34
  :write, :write_concern,
37
35
  :retry_reads, :max_read_retries, :read_retry_interval,
38
36
  :retry_writes, :max_write_retries,
37
+ :max_adaptive_retries, :enable_overload_retargeting,
38
+ :timeout_ms,
39
39
 
40
40
  # Options which cannot currently be here:
41
41
  #
@@ -45,81 +45,84 @@ module Mongo
45
45
  # the cluster is initialized it no longer uses this timeout.
46
46
  # Unfortunately server selector reads server selection timeout out of
47
47
  # the cluster, and this behavior is required by Cluster#next_primary
48
- # which takes no arguments. When next_primary is removed we can revsit
48
+ # which takes no arguments. When next_primary is removed we can revisit
49
49
  # using the same cluster object with different server selection timeouts.
50
50
  ].freeze
51
51
 
52
52
  # Valid client options.
53
53
  #
54
54
  # @since 2.1.2
55
- VALID_OPTIONS = [
56
- :app_name,
57
- :auth_mech,
58
- :auth_mech_properties,
59
- :auth_source,
60
- :auto_encryption_options,
61
- :bg_error_backtrace,
62
- :cleanup,
63
- :compressors,
64
- :direct_connection,
65
- :connect,
66
- :connect_timeout,
67
- :database,
68
- :heartbeat_frequency,
69
- :id_generator,
70
- :load_balanced,
71
- :local_threshold,
72
- :logger,
73
- :log_prefix,
74
- :max_connecting,
75
- :max_idle_time,
76
- :max_pool_size,
77
- :max_read_retries,
78
- :max_write_retries,
79
- :min_pool_size,
80
- :monitoring,
81
- :monitoring_io,
82
- :password,
83
- :platform,
84
- :populator_io,
85
- :read,
86
- :read_concern,
87
- :read_retry_interval,
88
- :replica_set,
89
- :resolv_options,
90
- :retry_reads,
91
- :retry_writes,
92
- :scan,
93
- :sdam_proc,
94
- :server_api,
95
- :server_selection_timeout,
96
- :socket_timeout,
97
- :srv_max_hosts,
98
- :srv_service_name,
99
- :ssl,
100
- :ssl_ca_cert,
101
- :ssl_ca_cert_object,
102
- :ssl_ca_cert_string,
103
- :ssl_cert,
104
- :ssl_cert_object,
105
- :ssl_cert_string,
106
- :ssl_key,
107
- :ssl_key_object,
108
- :ssl_key_pass_phrase,
109
- :ssl_key_string,
110
- :ssl_verify,
111
- :ssl_verify_certificate,
112
- :ssl_verify_hostname,
113
- :ssl_verify_ocsp_endpoint,
114
- :timeout_ms,
115
- :tracing,
116
- :truncate_logs,
117
- :user,
118
- :wait_queue_timeout,
119
- :wrapping_libraries,
120
- :write,
121
- :write_concern,
122
- :zlib_compression_level,
55
+ VALID_OPTIONS = %i[
56
+ app_name
57
+ auth_mech
58
+ auth_mech_properties
59
+ auth_source
60
+ auto_encryption_options
61
+ bg_error_backtrace
62
+ cleanup
63
+ compressors
64
+ direct_connection
65
+ enable_overload_retargeting
66
+ connect
67
+ connect_timeout
68
+ database
69
+ heartbeat_frequency
70
+ id_generator
71
+ load_balanced
72
+ local_threshold
73
+ logger
74
+ log_prefix
75
+ max_adaptive_retries
76
+ max_connecting
77
+ max_idle_time
78
+ max_pool_size
79
+ max_read_retries
80
+ max_write_retries
81
+ min_pool_size
82
+ monitoring
83
+ monitoring_io
84
+ password
85
+ platform
86
+ populator_io
87
+ read
88
+ read_concern
89
+ read_retry_interval
90
+ replica_set
91
+ resolv_options
92
+ retry_reads
93
+ retry_writes
94
+ scan
95
+ sdam_proc
96
+ server_api
97
+ server_monitoring_mode
98
+ server_selection_timeout
99
+ socket_timeout
100
+ srv_max_hosts
101
+ srv_service_name
102
+ ssl
103
+ ssl_ca_cert
104
+ ssl_ca_cert_object
105
+ ssl_ca_cert_string
106
+ ssl_cert
107
+ ssl_cert_object
108
+ ssl_cert_string
109
+ ssl_key
110
+ ssl_key_object
111
+ ssl_key_pass_phrase
112
+ ssl_key_string
113
+ ssl_verify
114
+ ssl_verify_certificate
115
+ ssl_verify_hostname
116
+ ssl_verify_ocsp_endpoint
117
+ timeout_ms
118
+ tracing
119
+ truncate_logs
120
+ user
121
+ wait_queue_timeout
122
+ wrapping_libraries
123
+ write
124
+ write_concern
125
+ zlib_compression_level
123
126
  ].freeze
124
127
 
125
128
  # The compression algorithms supported by the driver.
@@ -132,9 +135,9 @@ module Mongo
132
135
  ].freeze
133
136
 
134
137
  # The known server API versions.
135
- VALID_SERVER_API_VERSIONS = %w(
138
+ VALID_SERVER_API_VERSIONS = %w[
136
139
  1
137
- ).freeze
140
+ ].freeze
138
141
 
139
142
  # @return [ Mongo::Cluster ] cluster The cluster of servers for the client.
140
143
  attr_reader :cluster
@@ -149,6 +152,11 @@ module Mongo
149
152
  # auto-encryption behavior
150
153
  attr_reader :encrypter
151
154
 
155
+ # @return [ Mongo::Retryable::RetryPolicy ] The retry policy for
156
+ # backpressure and adaptive retries.
157
+ # @api private
158
+ attr_reader :retry_policy
159
+
152
160
  # Delegate command and collections execution to the current database.
153
161
  def_delegators :@database, :command, :collections
154
162
 
@@ -178,9 +186,10 @@ module Mongo
178
186
  # @since 2.0.0
179
187
  def ==(other)
180
188
  return false unless other.is_a?(Client)
189
+
181
190
  cluster == other.cluster && options == other.options
182
191
  end
183
- alias_method :eql?, :==
192
+ alias eql? ==
184
193
 
185
194
  # Get a collection object for the provided collection name.
186
195
  #
@@ -206,7 +215,7 @@ module Mongo
206
215
  #
207
216
  # @since 2.0.0
208
217
  def hash
209
- [cluster, options].hash
218
+ [ cluster, options ].hash
210
219
  end
211
220
 
212
221
  # Instantiate a new driver client.
@@ -230,8 +239,7 @@ module Mongo
230
239
  # analogous options present in the URI string.
231
240
  #
232
241
  # @option options [ String, Symbol ] :app_name Application name that is
233
- # printed to the mongod logs upon establishing a connection in server
234
- # versions >= 3.4.
242
+ # printed to the mongod logs upon establishing a connection
235
243
  # @option options [ Symbol ] :auth_mech The authentication mechanism to
236
244
  # use. One of :mongodb_cr, :mongodb_x509, :plain, :scram, :scram256
237
245
  # @option options [ Hash ] :auth_mech_properties
@@ -308,7 +316,6 @@ module Mongo
308
316
  # @option options [ String ] :password The user's password.
309
317
  # @option options [ String ] :platform Platform information to include in
310
318
  # the metadata printed to the mongod logs upon establishing a connection
311
- # in server versions >= 3.4.
312
319
  # @option options [ Hash ] :read The read preference options. The hash
313
320
  # may have the following items:
314
321
  # - *:mode* -- read preference specified as a symbol; valid values are
@@ -325,7 +332,7 @@ module Mongo
325
332
  # reads are enabled (which is the default). If false, modern retryable
326
333
  # reads are disabled and legacy retryable reads are enabled.
327
334
  # @option options [ true | false ] :retry_writes Retry writes once when
328
- # connected to a replica set or sharded cluster versions 3.6 and up.
335
+ # connected to a replica set or sharded cluster.
329
336
  # (Default is true.)
330
337
  # @option options [ true | false ] :scan Whether to scan all seeds
331
338
  # in constructor. The default in driver version 2.x is to do so;
@@ -534,12 +541,10 @@ module Mongo
534
541
  # The server API version is specified to be a string.
535
542
  # However, it is very annoying to always provide the number 1 as a string,
536
543
  # therefore cast to the string type here.
537
- if server_api = options[:server_api]
538
- if server_api.is_a?(Hash)
539
- server_api = Options::Redacted.new(server_api)
540
- if (version = server_api[:version]).is_a?(Integer)
541
- options[:server_api] = server_api.merge(version: version.to_s)
542
- end
544
+ if (server_api = options[:server_api]) && server_api.is_a?(Hash)
545
+ server_api = Options::Redacted.new(server_api)
546
+ if (version = server_api[:version]).is_a?(Integer)
547
+ options[:server_api] = server_api.merge(version: version.to_s)
543
548
  end
544
549
  end
545
550
 
@@ -552,27 +557,22 @@ module Mongo
552
557
  merged_options = default_options(options)
553
558
  options.each do |k, v|
554
559
  default_v = merged_options[k]
555
- if Hash === default_v
556
- v = default_v.merge(v)
557
- end
560
+ v = default_v.merge(v) if default_v.is_a?(Hash)
558
561
  merged_options[k] = v
559
562
  end
560
563
  options = merged_options
561
564
 
562
565
  options.keys.each do |k|
563
- if options[k].nil?
564
- options.delete(k)
565
- end
566
+ options.delete(k) if options[k].nil?
566
567
  end
567
568
 
568
569
  @options = validate_new_options!(options)
569
- =begin WriteConcern object support
570
- if @options[:write_concern].is_a?(WriteConcern::Base)
571
- # Cache the instance so that we do not needlessly reconstruct it.
572
- @write_concern = @options[:write_concern]
573
- @options[:write_concern] = @write_concern.options
574
- end
575
- =end
570
+ # WriteConcern object support
571
+ # if @options[:write_concern].is_a?(WriteConcern::Base)
572
+ # # Cache the instance so that we do not needlessly reconstruct it.
573
+ # @write_concern = @options[:write_concern]
574
+ # @options[:write_concern] = @write_concern.options
575
+ # end
576
576
  @options.freeze
577
577
  validate_options!(addresses, is_srv: uri.is_a?(URI::SRVProtocol))
578
578
  validate_authentication_options!
@@ -585,11 +585,12 @@ module Mongo
585
585
  # set up without there being a cluster
586
586
  @monitoring = Monitoring.new(@options)
587
587
 
588
- if sdam_proc
589
- sdam_proc.call(self)
590
- end
588
+ sdam_proc.call(self) if sdam_proc
591
589
 
592
590
  @connect_lock = Mutex.new
591
+ @retry_policy = Retryable::RetryPolicy.new(
592
+ max_retries: @options[:max_adaptive_retries] || Retryable::Backpressure::DEFAULT_MAX_RETRIES
593
+ )
593
594
  @connect_lock.synchronize do
594
595
  @cluster = Cluster.new(
595
596
  addresses,
@@ -600,30 +601,29 @@ module Mongo
600
601
 
601
602
  begin
602
603
  # Unset monitoring, it will be taken out of cluster from now on
603
- remove_instance_variable('@monitoring')
604
+ remove_instance_variable(:@monitoring)
604
605
 
605
606
  if @options[:auto_encryption_options]
606
607
  @connect_lock.synchronize do
607
608
  build_encrypter
608
609
  end
609
610
  end
610
-
611
- rescue
611
+ rescue StandardError
612
612
  begin
613
613
  @cluster.close
614
- rescue => e
615
- log_warn("Eror closing cluster in client constructor's exception handler: #{e.class}: #{e}")
614
+ rescue StandardError => e
615
+ log_warn("Error closing cluster in client constructor's exception handler: #{e.class}: #{e}")
616
616
  # Drop this exception so that the original exception is raised
617
617
  end
618
618
  raise
619
619
  end
620
620
 
621
- if block_given?
622
- begin
623
- yield(self)
624
- ensure
625
- close
626
- end
621
+ return unless block_given?
622
+
623
+ begin
624
+ yield(self)
625
+ ensure
626
+ close
627
627
  end
628
628
  end
629
629
 
@@ -632,7 +632,7 @@ module Mongo
632
632
  # We share clusters when a new client with different CRUD_OPTIONS
633
633
  # is requested; therefore, cluster should not be getting any of these
634
634
  # options upon instantiation
635
- options.reject do |key, value|
635
+ options.reject do |key, _value|
636
636
  CRUD_OPTIONS.include?(key.to_sym)
637
637
  end.merge(
638
638
  # but need to put the database back in for auth...
@@ -643,14 +643,12 @@ module Mongo
643
643
  # applications should read these values from client, not from cluster
644
644
  max_read_retries: options[:max_read_retries],
645
645
  read_retry_interval: options[:read_retry_interval],
646
- tracer: tracer,
646
+ tracer: tracer
647
647
  ).tap do |options|
648
648
  # If the client has a cluster already, forward srv_uri to the new
649
649
  # cluster to maintain SRV monitoring. If the client is brand new,
650
650
  # its constructor sets srv_uri manually.
651
- if cluster
652
- options.update(srv_uri: cluster.options[:srv_uri])
653
- end
651
+ options.update(srv_uri: cluster.options[:srv_uri]) if cluster
654
652
  end
655
653
  end
656
654
 
@@ -720,10 +718,10 @@ module Mongo
720
718
  # @since 2.5.0
721
719
  def server_selector
722
720
  @server_selector ||= if read_preference
723
- ServerSelector.get(read_preference)
724
- else
725
- ServerSelector.primary
726
- end
721
+ ServerSelector.get(read_preference)
722
+ else
723
+ ServerSelector.primary
724
+ end
727
725
  end
728
726
 
729
727
  # Get the read preference from the options passed to the client.
@@ -787,9 +785,7 @@ module Mongo
787
785
  Database.create(client)
788
786
  # We can't use the same cluster if some options that would affect it
789
787
  # have changed.
790
- if cluster_modifying?(opts)
791
- Cluster.create(client, monitoring: opts[:monitoring])
792
- end
788
+ Cluster.create(client, monitoring: opts[:monitoring]) if cluster_modifying?(opts)
793
789
  end
794
790
  end
795
791
 
@@ -815,12 +811,8 @@ module Mongo
815
811
  validate_new_options!(new_options).tap do |opts|
816
812
  # Our options are frozen
817
813
  options = @options.dup
818
- if options[:write] && opts[:write_concern]
819
- options.delete(:write)
820
- end
821
- if options[:write_concern] && opts[:write]
822
- options.delete(:write_concern)
823
- end
814
+ options.delete(:write) if options[:write] && opts[:write_concern]
815
+ options.delete(:write_concern) if options[:write_concern] && opts[:write]
824
816
 
825
817
  options.update(opts)
826
818
  @options = options.freeze
@@ -912,13 +904,15 @@ module Mongo
912
904
  addresses = cluster.addresses.map(&:to_s)
913
905
 
914
906
  @connect_lock.synchronize do
915
- do_close rescue nil
907
+ begin
908
+ do_close
909
+ rescue StandardError
910
+ nil
911
+ end
916
912
 
917
913
  @cluster = Cluster.new(addresses, monitoring, cluster_options)
918
914
 
919
- if @options[:auto_encryption_options]
920
- build_encrypter
921
- end
915
+ build_encrypter if @options[:auto_encryption_options]
922
916
 
923
917
  @closed = false
924
918
  end
@@ -951,7 +945,7 @@ module Mongo
951
945
  #
952
946
  # @since 2.0.5
953
947
  def database_names(filter = {}, opts = {})
954
- list_databases(filter, true, opts).collect{ |info| info['name'] }
948
+ list_databases(filter, true, opts).collect { |info| info['name'] }
955
949
  end
956
950
 
957
951
  # Get info for each database.
@@ -1045,9 +1039,8 @@ module Mongo
1045
1039
  end
1046
1040
  end
1047
1041
 
1048
- # As of version 3.6 of the MongoDB server, a ``$changeStream`` pipeline stage is supported
1049
- # in the aggregation framework. As of version 4.0, this stage allows users to request that
1050
- # notifications are sent for all changes that occur in the client's cluster.
1042
+ # Allows users to request that notifications are sent for all changes that
1043
+ # occur in the client's cluster.
1051
1044
  #
1052
1045
  # @example Get change notifications for the client's cluster.
1053
1046
  # client.watch([{ '$match' => { operationType: { '$in' => ['insert', 'replace'] } } }])
@@ -1093,7 +1086,6 @@ module Mongo
1093
1086
  # @option options [ BSON::Timestamp ] :start_at_operation_time Only return
1094
1087
  # changes that occurred at or after the specified timestamp. Any command run
1095
1088
  # against the server will return a cluster time that can be used here.
1096
- # Only recognized by server versions 4.0+.
1097
1089
  # @option options [ Object ] :comment A user-provided
1098
1090
  # comment to attach to this command.
1099
1091
  # @option options [ Boolean ] :show_expanded_events Enables the server to
@@ -1119,7 +1111,8 @@ module Mongo
1119
1111
  Mongo::Collection::View.new(self["#{Database::COMMAND}.aggregate"], {}, view_options),
1120
1112
  pipeline,
1121
1113
  Mongo::Collection::View::ChangeStream::CLUSTER,
1122
- options)
1114
+ options
1115
+ )
1123
1116
  end
1124
1117
 
1125
1118
  # Returns a session to use for operations if possible.
@@ -1165,7 +1158,7 @@ module Mongo
1165
1158
  # @option options [ Session ] :session The session to validate and return.
1166
1159
  #
1167
1160
  # @api private
1168
- def with_session(options = {}, &block)
1161
+ def with_session(options = {})
1169
1162
  # TODO: Add this back in RUBY-3174.
1170
1163
  # assert_not_closed
1171
1164
 
@@ -1173,9 +1166,7 @@ module Mongo
1173
1166
 
1174
1167
  yield session
1175
1168
  ensure
1176
- if session && session.implicit?
1177
- session.end_session
1178
- end
1169
+ session.end_session if session && session.implicit?
1179
1170
  end
1180
1171
 
1181
1172
  class << self
@@ -1185,12 +1176,10 @@ module Mongo
1185
1176
  # @api private
1186
1177
  def canonicalize_ruby_options(options)
1187
1178
  Options::Redacted.new(Hash[options.map do |k, v|
1188
- if k == :auth_mech_properties || k == 'auth_mech_properties'
1189
- if v
1190
- v = Hash[v.map { |pk, pv| [pk.downcase, pv] }]
1191
- end
1179
+ if [ :auth_mech_properties, 'auth_mech_properties' ].include?(k) && v
1180
+ v = Hash[v.map { |pk, pv| [ pk.downcase, pv ] }]
1192
1181
  end
1193
- [k, v]
1182
+ [ k, v ]
1194
1183
  end])
1195
1184
  end
1196
1185
  end
@@ -1227,7 +1216,7 @@ module Mongo
1227
1216
  @tracer ||= Tracing.create_tracer(
1228
1217
  enabled: tracing_opts[:enabled],
1229
1218
  query_text_max_length: tracing_opts[:query_text_max_length],
1230
- otel_tracer: tracing_opts[:tracer],
1219
+ otel_tracer: tracing_opts[:tracer]
1231
1220
  )
1232
1221
  end
1233
1222
 
@@ -1267,9 +1256,7 @@ module Mongo
1267
1256
  # options to override URI options, even when the Ruby option uses the
1268
1257
  # deprecated :write key and the URI option uses the current
1269
1258
  # :write_concern key
1270
- if options[:write]
1271
- uri_options.delete(:write_concern)
1272
- end
1259
+ uri_options.delete(:write_concern) if options[:write]
1273
1260
 
1274
1261
  processed[:options] = uri_options.merge(options)
1275
1262
 
@@ -1291,7 +1278,7 @@ module Mongo
1291
1278
  processed[:options] = options
1292
1279
 
1293
1280
  addresses.each do |addr|
1294
- if addr =~ /\Amongodb(\+srv)?:\/\//i
1281
+ if %r{\Amongodb(\+srv)?://}i.match?(addr)
1295
1282
  raise ArgumentError, "Host '#{addr}' should not contain protocol. Did you mean to not use an array?"
1296
1283
  end
1297
1284
  end
@@ -1311,13 +1298,9 @@ module Mongo
1311
1298
  # passed into the Client constructor.
1312
1299
  def default_options(options)
1313
1300
  Database::DEFAULT_OPTIONS.dup.tap do |default_options|
1314
- if options[:auth_mech] || options[:user]
1315
- default_options[:auth_source] = Auth::User.default_auth_source(options)
1316
- end
1301
+ default_options[:auth_source] = Auth::User.default_auth_source(options) if options[:auth_mech] || options[:user]
1317
1302
 
1318
- if options[:auth_mech] == :gssapi
1319
- default_options[:auth_mech_properties] = { service_name: 'mongodb' }
1320
- end
1303
+ default_options[:auth_mech_properties] = { service_name: 'mongodb' } if options[:auth_mech] == :gssapi
1321
1304
 
1322
1305
  default_options[:retry_reads] = true
1323
1306
  default_options[:retry_writes] = true
@@ -1353,19 +1336,17 @@ module Mongo
1353
1336
  #
1354
1337
  # @api private
1355
1338
  def get_session!(options = {})
1356
- if options[:session]
1357
- return options[:session].validate!(self)
1358
- end
1339
+ return options[:session].validate!(self) if options[:session]
1359
1340
 
1360
1341
  cluster.validate_session_support!(timeout: timeout_sec)
1361
1342
 
1362
- options = {implicit: true}.update(options)
1343
+ options = { implicit: true }.update(options)
1363
1344
 
1364
1345
  server_session = if options[:implicit]
1365
- nil
1366
- else
1367
- cluster.session_pool.checkout
1368
- end
1346
+ nil
1347
+ else
1348
+ cluster.session_pool.checkout
1349
+ end
1369
1350
 
1370
1351
  Session.new(server_session, self, options)
1371
1352
  end
@@ -1400,6 +1381,7 @@ module Mongo
1400
1381
  # but does not check for interactions between combinations of options.
1401
1382
  def validate_new_options!(opts)
1402
1383
  return Options::Redacted.new unless opts
1384
+
1403
1385
  if opts[:read_concern]
1404
1386
  # Raise an error for non user-settable options
1405
1387
  if opts[:read_concern][:after_cluster_time]
@@ -1409,34 +1391,28 @@ module Mongo
1409
1391
  end
1410
1392
 
1411
1393
  given_keys = opts[:read_concern].keys.map(&:to_s)
1412
- allowed_keys = ['level']
1394
+ allowed_keys = [ 'level' ]
1413
1395
  invalid_keys = given_keys - allowed_keys
1414
1396
  # Warn that options are invalid but keep it and forward to the server
1415
- unless invalid_keys.empty?
1416
- log_warn("Read concern has invalid keys: #{invalid_keys.join(',')}.")
1417
- end
1397
+ log_warn("Read concern has invalid keys: #{invalid_keys.join(',')}.") unless invalid_keys.empty?
1418
1398
  end
1419
1399
 
1420
1400
  if server_api = opts[:server_api]
1421
- unless server_api.is_a?(Hash)
1422
- raise ArgumentError, ":server_api value must be a hash: #{server_api}"
1423
- end
1401
+ raise ArgumentError, ":server_api value must be a hash: #{server_api}" unless server_api.is_a?(Hash)
1424
1402
 
1425
- extra_keys = server_api.keys - %w(version strict deprecation_errors)
1403
+ extra_keys = server_api.keys - %w[version strict deprecation_errors]
1426
1404
  unless extra_keys.empty?
1427
1405
  raise ArgumentError, "Unknown keys under :server_api: #{extra_keys.map(&:inspect).join(', ')}"
1428
1406
  end
1429
1407
 
1430
- if version = server_api[:version]
1431
- unless VALID_SERVER_API_VERSIONS.include?(version)
1432
- raise ArgumentError, "Unknown server API version: #{version}"
1433
- end
1408
+ if (version = server_api[:version]) && !VALID_SERVER_API_VERSIONS.include?(version)
1409
+ raise ArgumentError, "Unknown server API version: #{version}"
1434
1410
  end
1435
1411
  end
1436
1412
 
1437
1413
  Lint.validate_underscore_read_preference(opts[:read])
1438
1414
  Lint.validate_read_concern_option(opts[:read_concern])
1439
- opts.each.inject(Options::Redacted.new) do |_options, (k, v)|
1415
+ opts.each.each_with_object(Options::Redacted.new) do |(k, v), _options|
1440
1416
  key = k.to_sym
1441
1417
  if VALID_OPTIONS.include?(key)
1442
1418
  validate_max_min_pool_size!(key, opts)
@@ -1445,13 +1421,9 @@ module Mongo
1445
1421
  if key == :compressors
1446
1422
  compressors = valid_compressors(v)
1447
1423
 
1448
- if compressors.include?('snappy')
1449
- validate_snappy_compression!
1450
- end
1424
+ validate_snappy_compression! if compressors.include?('snappy')
1451
1425
 
1452
- if compressors.include?('zstd')
1453
- validate_zstd_compression!
1454
- end
1426
+ validate_zstd_compression! if compressors.include?('zstd')
1455
1427
 
1456
1428
  _options[key] = compressors unless compressors.empty?
1457
1429
  elsif key == :srv_max_hosts
@@ -1466,7 +1438,6 @@ module Mongo
1466
1438
  else
1467
1439
  log_warn("Unsupported client option '#{k}'. It will be ignored.")
1468
1440
  end
1469
- _options
1470
1441
  end
1471
1442
  end
1472
1443
 
@@ -1480,7 +1451,7 @@ module Mongo
1480
1451
 
1481
1452
  connect = options[:connect]&.to_sym
1482
1453
 
1483
- if connect && !%i(direct replica_set sharded load_balanced).include?(connect)
1454
+ if connect && !%i[direct replica_set sharded load_balanced].include?(connect)
1484
1455
  raise ArgumentError, "Invalid :connect option value: #{connect}"
1485
1456
  end
1486
1457
 
@@ -1490,72 +1461,69 @@ module Mongo
1490
1461
  end
1491
1462
  # When a new client is created, we get the list of seed addresses
1492
1463
  if addresses && addresses.length > 1
1493
- raise ArgumentError, "direct_connection=true cannot be used with multiple seeds"
1464
+ raise ArgumentError, 'direct_connection=true cannot be used with multiple seeds'
1494
1465
  end
1466
+
1495
1467
  # When a client is copied using #with, we have a cluster
1496
1468
  if cluster && !cluster.topology.is_a?(Mongo::Cluster::Topology::Single)
1497
- raise ArgumentError, "direct_connection=true cannot be used with topologies other than Single (this client is #{cluster.topology.class.name.sub(/.*::/, '')})"
1469
+ raise ArgumentError,
1470
+ "direct_connection=true cannot be used with topologies other than Single (this client is #{cluster.topology.class.name.sub(
1471
+ /.*::/, ''
1472
+ )})"
1498
1473
  end
1499
1474
  end
1500
1475
 
1501
1476
  if options[:load_balanced]
1502
1477
  if addresses && addresses.length > 1
1503
- raise ArgumentError, "load_balanced=true cannot be used with multiple seeds"
1478
+ raise ArgumentError, 'load_balanced=true cannot be used with multiple seeds'
1504
1479
  end
1505
1480
 
1506
1481
  if options[:direct_connection]
1507
- raise ArgumentError, "direct_connection=true cannot be used with load_balanced=true"
1482
+ raise ArgumentError, 'direct_connection=true cannot be used with load_balanced=true'
1508
1483
  end
1509
1484
 
1510
1485
  if connect && connect != :load_balanced
1511
1486
  raise ArgumentError, "connect=#{connect} cannot be used with load_balanced=true"
1512
1487
  end
1513
1488
 
1514
- if options[:replica_set]
1515
- raise ArgumentError, "load_balanced=true cannot be used with replica_set option"
1516
- end
1489
+ raise ArgumentError, 'load_balanced=true cannot be used with replica_set option' if options[:replica_set]
1517
1490
  end
1518
1491
 
1519
1492
  if connect == :load_balanced
1520
1493
  if addresses && addresses.length > 1
1521
- raise ArgumentError, "connect=load_balanced cannot be used with multiple seeds"
1494
+ raise ArgumentError, 'connect=load_balanced cannot be used with multiple seeds'
1522
1495
  end
1523
1496
 
1524
- if options[:replica_set]
1525
- raise ArgumentError, "connect=load_balanced cannot be used with replica_set option"
1526
- end
1497
+ raise ArgumentError, 'connect=load_balanced cannot be used with replica_set option' if options[:replica_set]
1527
1498
  end
1528
1499
 
1529
1500
  if options[:direct_connection] == false && connect && connect == :direct
1530
1501
  raise ArgumentError, "Conflicting client options: direct_connection=false and connect=#{connect}"
1531
1502
  end
1532
1503
 
1533
- %i(connect_timeout socket_timeout).each do |key|
1534
- if value = options[key]
1535
- unless Numeric === value
1536
- raise ArgumentError, "#{key} must be a non-negative number: #{value}"
1537
- end
1538
- if value < 0
1539
- raise ArgumentError, "#{key} must be a non-negative number: #{value}"
1540
- end
1541
- end
1504
+ %i[connect_timeout socket_timeout].each do |key|
1505
+ next unless value = options[key]
1506
+ raise ArgumentError, "#{key} must be a non-negative number: #{value}" unless value.is_a?(Numeric)
1507
+ raise ArgumentError, "#{key} must be a non-negative number: #{value}" if value < 0
1542
1508
  end
1543
1509
 
1544
1510
  if value = options[:bg_error_backtrace]
1545
1511
  case value
1546
1512
  when Integer
1547
1513
  if value <= 0
1548
- raise ArgumentError, ":bg_error_backtrace option value must be true, false, nil or a positive integer: #{value}"
1514
+ raise ArgumentError,
1515
+ ":bg_error_backtrace option value must be true, false, nil or a positive integer: #{value}"
1549
1516
  end
1550
1517
  when true
1551
1518
  # OK
1552
1519
  else
1553
- raise ArgumentError, ":bg_error_backtrace option value must be true, false, nil or a positive integer: #{value}"
1520
+ raise ArgumentError,
1521
+ ":bg_error_backtrace option value must be true, false, nil or a positive integer: #{value}"
1554
1522
  end
1555
1523
  end
1556
1524
 
1557
1525
  if libraries = options[:wrapping_libraries]
1558
- unless Array === libraries
1526
+ unless libraries.is_a?(Array)
1559
1527
  raise ArgumentError, ":wrapping_libraries must be an array of hashes: #{libraries}"
1560
1528
  end
1561
1529
 
@@ -1564,45 +1532,33 @@ module Mongo
1564
1532
  end
1565
1533
 
1566
1534
  libraries.each do |library|
1567
- unless Hash === library
1568
- raise ArgumentError, ":wrapping_libraries element is not a hash: #{library}"
1569
- end
1535
+ raise ArgumentError, ":wrapping_libraries element is not a hash: #{library}" unless library.is_a?(Hash)
1570
1536
 
1571
- if library.empty?
1572
- raise ArgumentError, ":wrapping_libraries element is empty"
1573
- end
1537
+ raise ArgumentError, ':wrapping_libraries element is empty' if library.empty?
1574
1538
 
1575
- unless (library.keys - %i(name platform version)).empty?
1576
- raise ArgumentError, ":wrapping_libraries element has invalid keys (allowed keys: :name, :platform, :version): #{library}"
1539
+ unless (library.keys - %i[name platform version]).empty?
1540
+ raise ArgumentError,
1541
+ ":wrapping_libraries element has invalid keys (allowed keys: :name, :platform, :version): #{library}"
1577
1542
  end
1578
1543
 
1579
- library.each do |key, value|
1580
- if value.include?('|')
1581
- raise ArgumentError, ":wrapping_libraries element value cannot include '|': #{value}"
1582
- end
1544
+ library.each do |_key, value|
1545
+ raise ArgumentError, ":wrapping_libraries element value cannot include '|': #{value}" if value.include?('|')
1583
1546
  end
1584
1547
  end
1585
1548
  end
1586
1549
 
1587
1550
  if options[:srv_max_hosts] && options[:srv_max_hosts] > 0
1588
- if options[:replica_set]
1589
- raise ArgumentError, ":srv_max_hosts > 0 cannot be used with :replica_set option"
1590
- end
1551
+ raise ArgumentError, ':srv_max_hosts > 0 cannot be used with :replica_set option' if options[:replica_set]
1591
1552
 
1592
- if options[:load_balanced]
1593
- raise ArgumentError, ":srv_max_hosts > 0 cannot be used with :load_balanced=true"
1594
- end
1553
+ raise ArgumentError, ':srv_max_hosts > 0 cannot be used with :load_balanced=true' if options[:load_balanced]
1595
1554
  end
1596
1555
 
1597
- unless is_srv.nil? || is_srv
1598
- if options[:srv_max_hosts]
1599
- raise ArgumentError, ":srv_max_hosts cannot be used on non-SRV URI"
1600
- end
1556
+ return if is_srv.nil? || is_srv
1557
+ raise ArgumentError, ':srv_max_hosts cannot be used on non-SRV URI' if options[:srv_max_hosts]
1601
1558
 
1602
- if options[:srv_service_name]
1603
- raise ArgumentError, ":srv_service_name cannot be used on non-SRV URI"
1604
- end
1605
- end
1559
+ return unless options[:srv_service_name]
1560
+
1561
+ raise ArgumentError, ':srv_service_name cannot be used on non-SRV URI'
1606
1562
  end
1607
1563
 
1608
1564
  # Validates all authentication-related options after they are set on the client
@@ -1626,15 +1582,13 @@ module Mongo
1626
1582
  return
1627
1583
  end
1628
1584
 
1629
- if !Mongo::Auth::SOURCES.key?(auth_mech)
1630
- raise Mongo::Auth::InvalidMechanism.new(auth_mech)
1631
- end
1585
+ raise Mongo::Auth::InvalidMechanism.new(auth_mech) unless Mongo::Auth::SOURCES.key?(auth_mech)
1632
1586
 
1633
- if user.nil? && !%i(aws mongodb_x509).include?(auth_mech)
1587
+ if user.nil? && !%i[aws mongodb_x509].include?(auth_mech)
1634
1588
  raise Mongo::Auth::InvalidConfiguration, "Username is required for auth mechanism #{auth_mech}"
1635
1589
  end
1636
1590
 
1637
- if password.nil? && !%i(aws gssapi mongodb_x509).include?(auth_mech)
1591
+ if password.nil? && !%i[aws gssapi mongodb_x509].include?(auth_mech)
1638
1592
  raise Mongo::Auth::InvalidConfiguration, "Password is required for auth mechanism #{auth_mech}"
1639
1593
  end
1640
1594
 
@@ -1643,62 +1597,63 @@ module Mongo
1643
1597
  end
1644
1598
 
1645
1599
  if auth_mech == :aws && user && !password
1646
- raise Mongo::Auth::InvalidConfiguration, 'Username is provided but password is not provided for :aws auth mechanism'
1600
+ raise Mongo::Auth::InvalidConfiguration,
1601
+ 'Username is provided but password is not provided for :aws auth mechanism'
1647
1602
  end
1648
1603
 
1649
- if %i(aws gssapi mongodb_x509).include?(auth_mech)
1650
- if !['$external', nil].include?(auth_source)
1651
- raise Mongo::Auth::InvalidConfiguration, "#{auth_source} is an invalid auth source for #{auth_mech}; valid options are $external and nil"
1604
+ if %i[aws gssapi mongodb_x509].include?(auth_mech)
1605
+ unless [ '$external', nil ].include?(auth_source)
1606
+ raise Mongo::Auth::InvalidConfiguration,
1607
+ "#{auth_source} is an invalid auth source for #{auth_mech}; valid options are $external and nil"
1652
1608
  end
1653
- else
1609
+ elsif auth_source == ''
1654
1610
  # Auth source is the database name, and thus cannot be the empty string.
1655
- if auth_source == ''
1656
- raise Mongo::Auth::InvalidConfiguration, "Auth source cannot be empty for auth mechanism #{auth_mech}"
1657
- end
1611
+ raise Mongo::Auth::InvalidConfiguration, "Auth source cannot be empty for auth mechanism #{auth_mech}"
1658
1612
  end
1659
1613
 
1660
- if mech_properties && !%i(aws gssapi).include?(auth_mech)
1661
- raise Mongo::Auth::InvalidConfiguration, ":mechanism_properties are not supported for auth mechanism #{auth_mech}"
1662
- end
1614
+ return unless mech_properties && !%i[aws gssapi].include?(auth_mech)
1615
+
1616
+ raise Mongo::Auth::InvalidConfiguration,
1617
+ ":mechanism_properties are not supported for auth mechanism #{auth_mech}"
1663
1618
  end
1664
1619
 
1665
1620
  def valid_compressors(compressors)
1666
1621
  compressors.select do |compressor|
1667
- if !VALID_COMPRESSORS.include?(compressor)
1668
- log_warn("Unsupported compressor '#{compressor}' in list '#{compressors}'. " +
1669
- "This compressor will not be used.")
1670
- false
1671
- else
1622
+ if VALID_COMPRESSORS.include?(compressor)
1672
1623
 
1673
1624
  true
1625
+ else
1626
+ log_warn("Unsupported compressor '#{compressor}' in list '#{compressors}'. " +
1627
+ 'This compressor will not be used.')
1628
+ false
1674
1629
  end
1675
1630
  end
1676
1631
  end
1677
1632
 
1678
1633
  def validate_snappy_compression!
1679
1634
  return if defined?(Snappy)
1635
+
1680
1636
  require 'snappy'
1681
1637
  rescue LoadError => e
1682
- raise Error::UnmetDependency, "Cannot enable snappy compression because the snappy gem " \
1683
- "has not been installed. Add \"gem 'snappy'\" to your Gemfile and run " \
1684
- "\"bundle install\" to install the gem. (#{e.class}: #{e})"
1638
+ raise Error::UnmetDependency, 'Cannot enable snappy compression because the snappy gem ' \
1639
+ "has not been installed. Add \"gem 'snappy'\" to your Gemfile and run " \
1640
+ "\"bundle install\" to install the gem. (#{e.class}: #{e})"
1685
1641
  end
1686
1642
 
1687
1643
  def validate_zstd_compression!
1688
1644
  return if defined?(Zstd)
1645
+
1689
1646
  require 'zstd-ruby'
1690
1647
  rescue LoadError => e
1691
- raise Error::UnmetDependency, "Cannot enable zstd compression because the zstd-ruby gem " \
1692
- "has not been installed. Add \"gem 'zstd-ruby'\" to your Gemfile and run " \
1693
- "\"bundle install\" to install the gem. (#{e.class}: #{e})"
1648
+ raise Error::UnmetDependency, 'Cannot enable zstd compression because the zstd-ruby gem ' \
1649
+ "has not been installed. Add \"gem 'zstd-ruby'\" to your Gemfile and run " \
1650
+ "\"bundle install\" to install the gem. (#{e.class}: #{e})"
1694
1651
  end
1695
1652
 
1696
1653
  def validate_max_min_pool_size!(option, opts)
1697
1654
  if option == :min_pool_size && opts[:min_pool_size]
1698
1655
  max = opts[:max_pool_size] || Server::ConnectionPool::DEFAULT_MAX_SIZE
1699
- if max != 0 && opts[:min_pool_size] > max
1700
- raise Error::InvalidMinPoolSize.new(opts[:min_pool_size], max)
1701
- end
1656
+ raise Error::InvalidMinPoolSize.new(opts[:min_pool_size], max) if max != 0 && opts[:min_pool_size] > max
1702
1657
  end
1703
1658
  true
1704
1659
  end
@@ -1713,9 +1668,7 @@ module Mongo
1713
1668
  def validate_max_connecting!(option, opts)
1714
1669
  if option == :max_connecting && opts.key?(:max_connecting)
1715
1670
  max_connecting = opts[:max_connecting] || Server::ConnectionPool::DEFAULT_MAX_CONNECTING
1716
- if max_connecting <= 0
1717
- raise Error::InvalidMaxConnecting.new(opts[:max_connecting])
1718
- end
1671
+ raise Error::InvalidMaxConnecting.new(opts[:max_connecting]) if max_connecting <= 0
1719
1672
  end
1720
1673
  true
1721
1674
  end
@@ -1727,7 +1680,8 @@ module Mongo
1727
1680
  # for custom classes implementing key access ([]).
1728
1681
  # Instead reject common cases of strings and symbols.
1729
1682
  if read.is_a?(String) || read.is_a?(Symbol)
1730
- raise Error::InvalidReadOption.new(read, "the read preference must be specified as a hash: { mode: #{read.inspect} }")
1683
+ raise Error::InvalidReadOption.new(read,
1684
+ "the read preference must be specified as a hash: { mode: #{read.inspect} }")
1731
1685
  end
1732
1686
 
1733
1687
  if mode = read[:mode]
@@ -1741,9 +1695,10 @@ module Mongo
1741
1695
  end
1742
1696
 
1743
1697
  def assert_not_closed
1744
- if closed?
1745
- raise Error::ClientClosed, "The client was closed and is not usable for operations. Call #reconnect to reset this client instance or create a new client instance"
1746
- end
1698
+ return unless closed?
1699
+
1700
+ raise Error::ClientClosed,
1701
+ 'The client was closed and is not usable for operations. Call #reconnect to reset this client instance or create a new client instance'
1747
1702
  end
1748
1703
  end
1749
1704
  end