mongo 2.19.1 → 2.21.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 (356) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +40 -1
  3. data/Rakefile +83 -174
  4. data/lib/mongo/address.rb +22 -3
  5. data/lib/mongo/auth/aws/credentials_retriever.rb +70 -17
  6. data/lib/mongo/auth/base.rb +1 -1
  7. data/lib/mongo/bulk_write.rb +35 -2
  8. data/lib/mongo/client.rb +38 -6
  9. data/lib/mongo/client_encryption.rb +6 -3
  10. data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -1
  11. data/lib/mongo/cluster/sdam_flow.rb +20 -7
  12. data/lib/mongo/cluster/topology/base.rb +16 -0
  13. data/lib/mongo/cluster.rb +41 -5
  14. data/lib/mongo/collection/helpers.rb +1 -1
  15. data/lib/mongo/collection/view/aggregation/behavior.rb +131 -0
  16. data/lib/mongo/collection/view/aggregation.rb +33 -99
  17. data/lib/mongo/collection/view/builder/aggregation.rb +1 -7
  18. data/lib/mongo/collection/view/change_stream.rb +80 -27
  19. data/lib/mongo/collection/view/iterable.rb +92 -60
  20. data/lib/mongo/collection/view/map_reduce.rb +25 -8
  21. data/lib/mongo/collection/view/readable.rb +79 -30
  22. data/lib/mongo/collection/view/writable.rb +109 -48
  23. data/lib/mongo/collection/view.rb +44 -3
  24. data/lib/mongo/collection.rb +185 -26
  25. data/lib/mongo/config.rb +2 -2
  26. data/lib/mongo/crypt/auto_encrypter.rb +4 -6
  27. data/lib/mongo/crypt/binding.rb +4 -4
  28. data/lib/mongo/crypt/context.rb +20 -14
  29. data/lib/mongo/crypt/encryption_io.rb +56 -26
  30. data/lib/mongo/crypt/explicit_encrypter.rb +49 -20
  31. data/lib/mongo/crypt/explicit_encryption_context.rb +17 -11
  32. data/lib/mongo/crypt/kms/azure/credentials_retriever.rb +22 -6
  33. data/lib/mongo/crypt/kms/gcp/credentials_retriever.rb +29 -4
  34. data/lib/mongo/csot_timeout_holder.rb +119 -0
  35. data/lib/mongo/cursor/kill_spec.rb +5 -2
  36. data/lib/mongo/cursor/nontailable.rb +27 -0
  37. data/lib/mongo/cursor.rb +86 -24
  38. data/lib/mongo/cursor_host.rb +82 -0
  39. data/lib/mongo/database/view.rb +81 -14
  40. data/lib/mongo/database.rb +88 -18
  41. data/lib/mongo/error/operation_failure.rb +209 -204
  42. data/lib/mongo/error/server_timeout_error.rb +12 -0
  43. data/lib/mongo/error/socket_timeout_error.rb +3 -1
  44. data/lib/mongo/error/timeout_error.rb +23 -0
  45. data/lib/mongo/error/transactions_not_supported.rb +34 -0
  46. data/lib/mongo/error.rb +3 -0
  47. data/lib/mongo/grid/fs_bucket.rb +48 -9
  48. data/lib/mongo/grid/stream/read.rb +15 -1
  49. data/lib/mongo/grid/stream/write.rb +21 -4
  50. data/lib/mongo/index/view.rb +77 -16
  51. data/lib/mongo/monitoring/event/secure.rb +1 -1
  52. data/lib/mongo/operation/context.rb +40 -2
  53. data/lib/mongo/operation/create_search_indexes/op_msg.rb +31 -0
  54. data/lib/mongo/operation/create_search_indexes.rb +15 -0
  55. data/lib/mongo/operation/delete/op_msg.rb +2 -1
  56. data/lib/mongo/operation/drop_search_index/op_msg.rb +33 -0
  57. data/lib/mongo/operation/drop_search_index.rb +15 -0
  58. data/lib/mongo/operation/find/op_msg.rb +45 -0
  59. data/lib/mongo/operation/get_more/op_msg.rb +33 -0
  60. data/lib/mongo/operation/insert/op_msg.rb +3 -2
  61. data/lib/mongo/operation/insert/result.rb +4 -2
  62. data/lib/mongo/operation/list_collections/result.rb +1 -1
  63. data/lib/mongo/operation/map_reduce/result.rb +1 -1
  64. data/lib/mongo/operation/op_msg_base.rb +3 -1
  65. data/lib/mongo/operation/result.rb +26 -5
  66. data/lib/mongo/operation/shared/executable.rb +55 -28
  67. data/lib/mongo/operation/shared/op_msg_executable.rb +4 -1
  68. data/lib/mongo/operation/shared/response_handling.rb +25 -27
  69. data/lib/mongo/operation/shared/sessions_supported.rb +1 -1
  70. data/lib/mongo/operation/shared/specifiable.rb +7 -0
  71. data/lib/mongo/operation/shared/timed.rb +52 -0
  72. data/lib/mongo/operation/shared/write.rb +4 -1
  73. data/lib/mongo/operation/update/op_msg.rb +2 -1
  74. data/lib/mongo/operation/update_search_index/op_msg.rb +34 -0
  75. data/lib/mongo/operation/update_search_index.rb +15 -0
  76. data/lib/mongo/operation.rb +4 -0
  77. data/lib/mongo/protocol/message.rb +1 -4
  78. data/lib/mongo/protocol/msg.rb +2 -2
  79. data/lib/mongo/retryable/base_worker.rb +28 -3
  80. data/lib/mongo/retryable/read_worker.rb +78 -36
  81. data/lib/mongo/retryable/write_worker.rb +59 -25
  82. data/lib/mongo/retryable.rb +8 -2
  83. data/lib/mongo/search_index/view.rb +232 -0
  84. data/lib/mongo/server/app_metadata/environment.rb +64 -9
  85. data/lib/mongo/server/app_metadata.rb +5 -4
  86. data/lib/mongo/server/connection.rb +11 -5
  87. data/lib/mongo/server/connection_base.rb +22 -2
  88. data/lib/mongo/server/connection_pool.rb +32 -14
  89. data/lib/mongo/server/description/features.rb +2 -1
  90. data/lib/mongo/server/description.rb +18 -5
  91. data/lib/mongo/server/monitor.rb +7 -4
  92. data/lib/mongo/server/pending_connection.rb +25 -8
  93. data/lib/mongo/server/{round_trip_time_averager.rb → round_trip_time_calculator.rb} +25 -7
  94. data/lib/mongo/server.rb +11 -6
  95. data/lib/mongo/server_selector/base.rb +54 -12
  96. data/lib/mongo/session/server_session/dirtyable.rb +52 -0
  97. data/lib/mongo/session/server_session.rb +3 -0
  98. data/lib/mongo/session/session_pool.rb +12 -18
  99. data/lib/mongo/session.rb +110 -9
  100. data/lib/mongo/socket/ssl.rb +131 -18
  101. data/lib/mongo/socket/tcp.rb +40 -6
  102. data/lib/mongo/socket.rb +154 -25
  103. data/lib/mongo/uri/options_mapper.rb +1 -0
  104. data/lib/mongo/uri.rb +0 -4
  105. data/lib/mongo/version.rb +1 -5
  106. data/lib/mongo.rb +2 -0
  107. data/mongo.gemspec +9 -18
  108. data/spec/atlas/atlas_connectivity_spec.rb +9 -9
  109. data/spec/atlas/operations_spec.rb +5 -5
  110. data/spec/faas/ruby-sam-app/Gemfile +9 -0
  111. data/spec/faas/ruby-sam-app/mongodb/Gemfile +4 -0
  112. data/spec/faas/ruby-sam-app/mongodb/app.rb +149 -0
  113. data/spec/faas/ruby-sam-app/template.yaml +48 -0
  114. data/spec/integration/client_side_encryption/auto_encryption_mongocryptd_spawn_spec.rb +2 -1
  115. data/spec/integration/client_side_encryption/auto_encryption_spec.rb +494 -487
  116. data/spec/integration/client_side_encryption/corpus_spec.rb +10 -2
  117. data/spec/integration/client_side_encryption/on_demand_aws_credentials_spec.rb +1 -1
  118. data/spec/integration/client_side_encryption/range_explicit_encryption_prose_spec.rb +67 -20
  119. data/spec/integration/client_side_operations_timeout/encryption_prose_spec.rb +131 -0
  120. data/spec/integration/connection_pool_populator_spec.rb +2 -0
  121. data/spec/integration/cursor_pinning_spec.rb +15 -60
  122. data/spec/integration/cursor_reaping_spec.rb +1 -1
  123. data/spec/integration/docs_examples_spec.rb +1 -1
  124. data/spec/integration/find_options_spec.rb +227 -0
  125. data/spec/integration/operation_failure_code_spec.rb +1 -1
  126. data/spec/integration/operation_failure_message_spec.rb +3 -3
  127. data/spec/integration/retryable_errors_spec.rb +2 -2
  128. data/spec/integration/retryable_reads_errors_spec.rb +196 -31
  129. data/spec/integration/retryable_writes_errors_spec.rb +156 -0
  130. data/spec/integration/sdam_error_handling_spec.rb +4 -1
  131. data/spec/integration/search_indexes_prose_spec.rb +172 -0
  132. data/spec/integration/server_spec.rb +4 -3
  133. data/spec/integration/transactions_api_examples_spec.rb +2 -0
  134. data/spec/kerberos/kerberos_spec.rb +4 -0
  135. data/spec/lite_spec_helper.rb +34 -20
  136. data/spec/mongo/auth/user/view_spec.rb +1 -1
  137. data/spec/mongo/caching_cursor_spec.rb +1 -1
  138. data/spec/mongo/client_encryption_spec.rb +1 -0
  139. data/spec/mongo/client_spec.rb +158 -4
  140. data/spec/mongo/cluster_spec.rb +36 -0
  141. data/spec/mongo/collection/view/aggregation_spec.rb +20 -40
  142. data/spec/mongo/collection/view/change_stream_spec.rb +3 -3
  143. data/spec/mongo/collection/view/explainable_spec.rb +2 -0
  144. data/spec/mongo/collection_crud_spec.rb +2 -1
  145. data/spec/mongo/collection_spec.rb +5 -6
  146. data/spec/mongo/crypt/auto_encrypter_spec.rb +14 -12
  147. data/spec/mongo/crypt/data_key_context_spec.rb +3 -1
  148. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +2 -2
  149. data/spec/mongo/crypt/handle_spec.rb +1 -1
  150. data/spec/mongo/cursor_spec.rb +26 -9
  151. data/spec/mongo/error/operation_failure_heavy_spec.rb +2 -2
  152. data/spec/mongo/operation/context_spec.rb +79 -0
  153. data/spec/mongo/operation/create/op_msg_spec.rb +106 -110
  154. data/spec/mongo/operation/delete/op_msg_spec.rb +6 -5
  155. data/spec/mongo/operation/find/op_msg_spec.rb +66 -0
  156. data/spec/mongo/operation/get_more/op_msg_spec.rb +65 -0
  157. data/spec/mongo/operation/insert/op_msg_spec.rb +128 -131
  158. data/spec/mongo/operation/insert_spec.rb +1 -1
  159. data/spec/mongo/operation/shared/csot/examples.rb +113 -0
  160. data/spec/mongo/query_cache_spec.rb +243 -225
  161. data/spec/mongo/retryable/write_worker_spec.rb +39 -0
  162. data/spec/mongo/retryable_spec.rb +1 -0
  163. data/spec/mongo/server/app_metadata/environment_spec.rb +135 -0
  164. data/spec/mongo/server/app_metadata_spec.rb +12 -2
  165. data/spec/mongo/server/connection_spec.rb +26 -0
  166. data/spec/mongo/server/round_trip_time_calculator_spec.rb +120 -0
  167. data/spec/mongo/session/session_pool_spec.rb +1 -16
  168. data/spec/mongo/session_transaction_spec.rb +15 -0
  169. data/spec/mongo/socket/ssl_spec.rb +0 -10
  170. data/spec/mongo/uri_spec.rb +0 -9
  171. data/spec/runners/change_streams/test.rb +2 -2
  172. data/spec/runners/crud/operation.rb +1 -1
  173. data/spec/runners/crud/test.rb +0 -8
  174. data/spec/runners/crud/verifier.rb +3 -1
  175. data/spec/runners/crud.rb +1 -1
  176. data/spec/runners/transactions/operation.rb +4 -6
  177. data/spec/runners/transactions/test.rb +12 -3
  178. data/spec/runners/unified/ambiguous_operations.rb +13 -0
  179. data/spec/runners/unified/assertions.rb +20 -3
  180. data/spec/runners/unified/change_stream_operations.rb +14 -24
  181. data/spec/runners/unified/crud_operations.rb +82 -47
  182. data/spec/runners/unified/ddl_operations.rb +38 -7
  183. data/spec/runners/unified/grid_fs_operations.rb +37 -2
  184. data/spec/runners/unified/search_index_operations.rb +63 -0
  185. data/spec/runners/unified/support_operations.rb +46 -9
  186. data/spec/runners/unified/test.rb +33 -12
  187. data/spec/runners/unified.rb +1 -1
  188. data/spec/solo/clean_exit_spec.rb +2 -0
  189. data/spec/spec_helper.rb +1 -1
  190. data/spec/spec_tests/client_side_operations_timeout_spec.rb +15 -0
  191. data/spec/spec_tests/data/change_streams_unified/change-streams-clusterTime.yml +3 -1
  192. data/spec/spec_tests/data/change_streams_unified/change-streams-disambiguatedPaths.yml +3 -1
  193. data/spec/spec_tests/data/change_streams_unified/change-streams-errors.yml +3 -1
  194. data/spec/spec_tests/data/change_streams_unified/change-streams-pre_and_post_images.yml +1 -1
  195. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-allowlist.yml +1 -1
  196. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +1 -1
  197. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +1 -1
  198. data/spec/spec_tests/data/client_side_encryption/badQueries.yml +2 -1
  199. data/spec/spec_tests/data/client_side_encryption/explain.yml +2 -2
  200. data/spec/spec_tests/data/client_side_encryption/fle2v2-BypassQueryAnalysis.yml +1 -0
  201. data/spec/spec_tests/data/client_side_encryption/fle2v2-Compact.yml +1 -0
  202. data/spec/spec_tests/data/client_side_encryption/fle2v2-CreateCollection.yml +1 -0
  203. data/spec/spec_tests/data/client_side_encryption/fle2v2-DecryptExistingData.yml +1 -0
  204. data/spec/spec_tests/data/client_side_encryption/fle2v2-Delete.yml +1 -0
  205. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-EncryptedFieldsMap.yml +1 -0
  206. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFields-vs-jsonSchema.yml +1 -0
  207. data/spec/spec_tests/data/client_side_encryption/fle2v2-EncryptedFieldsMap-defaults.yml +1 -0
  208. data/spec/spec_tests/data/client_side_encryption/fle2v2-FindOneAndUpdate.yml +1 -0
  209. data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Indexed.yml +1 -0
  210. data/spec/spec_tests/data/client_side_encryption/fle2v2-InsertFind-Unindexed.yml +1 -0
  211. data/spec/spec_tests/data/client_side_encryption/fle2v2-MissingKey.yml +1 -0
  212. data/spec/spec_tests/data/client_side_encryption/fle2v2-NoEncryption.yml +1 -0
  213. data/spec/spec_tests/data/client_side_encryption/fle2v2-Update.yml +1 -0
  214. data/spec/spec_tests/data/client_side_encryption/fle2v2-validatorAndPartialFieldExpression.yml +2 -1
  215. data/spec/spec_tests/data/client_side_encryption/timeoutMS.yml +67 -0
  216. data/spec/spec_tests/data/client_side_operations_timeout/bulkWrite.yml +87 -0
  217. data/spec/spec_tests/data/client_side_operations_timeout/change-streams.yml +358 -0
  218. data/spec/spec_tests/data/client_side_operations_timeout/close-cursors.yml +129 -0
  219. data/spec/spec_tests/data/client_side_operations_timeout/command-execution.yml +250 -0
  220. data/spec/spec_tests/data/client_side_operations_timeout/convenient-transactions.yml +113 -0
  221. data/spec/spec_tests/data/client_side_operations_timeout/cursors.yml +70 -0
  222. data/spec/spec_tests/data/client_side_operations_timeout/deprecated-options.yml +3982 -0
  223. data/spec/spec_tests/data/client_side_operations_timeout/error-transformations.yml +96 -0
  224. data/spec/spec_tests/data/client_side_operations_timeout/global-timeoutMS.yml +3236 -0
  225. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-advanced.yml +207 -0
  226. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-delete.yml +152 -0
  227. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-download.yml +182 -0
  228. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-find.yml +100 -0
  229. data/spec/spec_tests/data/client_side_operations_timeout/gridfs-upload.yml +249 -0
  230. data/spec/spec_tests/data/client_side_operations_timeout/legacy-timeouts.yml +204 -0
  231. data/spec/spec_tests/data/client_side_operations_timeout/non-tailable-cursors.yml +307 -0
  232. data/spec/spec_tests/data/client_side_operations_timeout/override-collection-timeoutMS.yml +1877 -0
  233. data/spec/spec_tests/data/client_side_operations_timeout/override-operation-timeoutMS.yml +1918 -0
  234. data/spec/spec_tests/data/client_side_operations_timeout/retryability-legacy-timeouts.yml +1676 -0
  235. data/spec/spec_tests/data/client_side_operations_timeout/retryability-timeoutMS.yml +2824 -0
  236. data/spec/spec_tests/data/client_side_operations_timeout/sessions-inherit-timeoutMS.yml +168 -0
  237. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-operation-timeoutMS.yml +171 -0
  238. data/spec/spec_tests/data/client_side_operations_timeout/sessions-override-timeoutMS.yml +168 -0
  239. data/spec/spec_tests/data/client_side_operations_timeout/tailable-awaitData.yml +247 -0
  240. data/spec/spec_tests/data/client_side_operations_timeout/tailable-non-awaitData.yml +181 -0
  241. data/spec/spec_tests/data/connection_string/invalid-uris.yml +0 -10
  242. data/spec/spec_tests/data/connection_string/valid-options.yml +13 -0
  243. data/spec/spec_tests/data/crud_unified/aggregate-write-readPreference.yml +6 -0
  244. data/spec/spec_tests/data/crud_unified/db-aggregate-write-readPreference.yml +6 -0
  245. data/spec/spec_tests/data/crud_unified/find-test-all-options.yml +377 -0
  246. data/spec/spec_tests/data/index_management/createSearchIndex.yml +64 -0
  247. data/spec/spec_tests/data/index_management/createSearchIndexes.yml +86 -0
  248. data/spec/spec_tests/data/index_management/dropSearchIndex.yml +43 -0
  249. data/spec/spec_tests/data/index_management/listSearchIndexes.yml +91 -0
  250. data/spec/spec_tests/data/index_management/updateSearchIndex.yml +46 -0
  251. data/spec/spec_tests/data/retryable_writes/unified/bulkWrite-serverErrors.yml +3 -6
  252. data/spec/spec_tests/data/retryable_writes/unified/insertOne-serverErrors.yml +3 -6
  253. data/spec/spec_tests/data/run_command_unified/runCommand.yml +319 -0
  254. data/spec/spec_tests/data/sessions_unified/driver-sessions-dirty-session-errors.yml +351 -0
  255. data/spec/spec_tests/data/unified/valid-pass/poc-crud.yml +1 -1
  256. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-writes.yml +7 -7
  257. data/spec/spec_tests/data/unified/valid-pass/poc-sessions.yml +3 -4
  258. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-convenient-api.yml +1 -1
  259. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-mongos-pin-auto.yml +1 -1
  260. data/spec/spec_tests/data/unified/valid-pass/poc-transactions.yml +3 -3
  261. data/spec/spec_tests/index_management_unified_spec.rb +13 -0
  262. data/spec/spec_tests/run_command_unified_spec.rb +13 -0
  263. data/spec/spec_tests/sdam_unified_spec.rb +2 -0
  264. data/spec/spec_tests/server_selection_rtt_spec.rb +6 -6
  265. data/spec/spec_tests/transactions_unified_spec.rb +2 -1
  266. data/spec/support/certificates/atlas-ocsp-ca.crt +89 -79
  267. data/spec/support/certificates/atlas-ocsp.crt +117 -122
  268. data/spec/support/certificates/retrieve-atlas-cert +1 -1
  269. data/spec/support/cluster_tools.rb +3 -3
  270. data/spec/support/common_shortcuts.rb +2 -2
  271. data/spec/support/constraints.rb +6 -0
  272. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Date.json +1 -1
  273. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalNoPrecision.json +1 -1
  274. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DecimalPrecision.json +1 -1
  275. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoubleNoPrecision.json +1 -1
  276. data/spec/support/crypt/encrypted_fields/range-encryptedFields-DoublePrecision.json +1 -1
  277. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Int.json +1 -1
  278. data/spec/support/crypt/encrypted_fields/range-encryptedFields-Long.json +1 -1
  279. data/spec/support/ocsp +1 -1
  280. data/spec/support/recording_logger.rb +27 -0
  281. data/spec/support/shared/session.rb +2 -2
  282. data/spec/support/spec_config.rb +5 -0
  283. data/spec/support/spec_setup.rb +2 -2
  284. data/spec/support/utils.rb +3 -1
  285. metadata +1329 -1368
  286. checksums.yaml.gz.sig +0 -0
  287. data/spec/mongo/server/round_trip_time_averager_spec.rb +0 -48
  288. data/spec/shared/LICENSE +0 -20
  289. data/spec/shared/bin/get-mongodb-download-url +0 -17
  290. data/spec/shared/bin/s3-copy +0 -45
  291. data/spec/shared/bin/s3-upload +0 -69
  292. data/spec/shared/lib/mrss/child_process_helper.rb +0 -80
  293. data/spec/shared/lib/mrss/cluster_config.rb +0 -231
  294. data/spec/shared/lib/mrss/constraints.rb +0 -378
  295. data/spec/shared/lib/mrss/docker_runner.rb +0 -295
  296. data/spec/shared/lib/mrss/eg_config_utils.rb +0 -51
  297. data/spec/shared/lib/mrss/event_subscriber.rb +0 -210
  298. data/spec/shared/lib/mrss/lite_constraints.rb +0 -238
  299. data/spec/shared/lib/mrss/server_version_registry.rb +0 -113
  300. data/spec/shared/lib/mrss/session_registry.rb +0 -69
  301. data/spec/shared/lib/mrss/session_registry_legacy.rb +0 -60
  302. data/spec/shared/lib/mrss/spec_organizer.rb +0 -179
  303. data/spec/shared/lib/mrss/utils.rb +0 -37
  304. data/spec/shared/share/Dockerfile.erb +0 -330
  305. data/spec/shared/share/haproxy-1.conf +0 -16
  306. data/spec/shared/share/haproxy-2.conf +0 -17
  307. data/spec/shared/shlib/config.sh +0 -27
  308. data/spec/shared/shlib/distro.sh +0 -74
  309. data/spec/shared/shlib/server.sh +0 -416
  310. data/spec/shared/shlib/set_env.sh +0 -169
  311. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Aggregate.yml +0 -241
  312. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Correctness.yml +0 -422
  313. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Delete.yml +0 -182
  314. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-FindOneAndUpdate.yml +0 -239
  315. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-InsertFind.yml +0 -235
  316. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Date-Update.yml +0 -252
  317. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Aggregate.yml +0 -1687
  318. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Correctness.yml +0 -293
  319. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Delete.yml +0 -905
  320. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-FindOneAndUpdate.yml +0 -1684
  321. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-InsertFind.yml +0 -1680
  322. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Decimal-Update.yml +0 -1697
  323. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Aggregate.yml +0 -329
  324. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Correctness.yml +0 -424
  325. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Delete.yml +0 -226
  326. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-FindOneAndUpdate.yml +0 -327
  327. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-InsertFind.yml +0 -319
  328. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DecimalPrecision-Update.yml +0 -336
  329. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Aggregate.yml +0 -913
  330. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Correctness.yml +0 -292
  331. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Delete.yml +0 -518
  332. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-FindOneAndUpdate.yml +0 -911
  333. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-InsertFind.yml +0 -907
  334. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Double-Update.yml +0 -924
  335. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Aggregate.yml +0 -325
  336. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Correctness.yml +0 -424
  337. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Delete.yml +0 -224
  338. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-FindOneAndUpdate.yml +0 -323
  339. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-InsertFind.yml +0 -319
  340. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-DoublePrecision-Update.yml +0 -338
  341. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Aggregate.yml +0 -241
  342. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Correctness.yml +0 -423
  343. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Delete.yml +0 -182
  344. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-FindOneAndUpdate.yml +0 -239
  345. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-InsertFind.yml +0 -235
  346. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Int-Update.yml +0 -254
  347. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Aggregate.yml +0 -241
  348. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Correctness.yml +0 -422
  349. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Delete.yml +0 -182
  350. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-FindOneAndUpdate.yml +0 -239
  351. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-InsertFind.yml +0 -235
  352. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-Long-Update.yml +0 -254
  353. data/spec/spec_tests/data/client_side_encryption/fle2v2-Range-WrongType.yml +0 -43
  354. data/spec/spec_tests/data/cmap/pool-clear-interrupt-immediately.yml +0 -49
  355. data.tar.gz.sig +0 -0
  356. metadata.gz.sig +0 -2
@@ -60,10 +60,15 @@ module Mongo
60
60
  result_combiner = ResultCombiner.new
61
61
  operations = op_combiner.combine
62
62
  validate_requests!
63
+ deadline = calculate_deadline
63
64
 
64
- client.send(:with_session, @options) do |session|
65
- context = Operation::Context.new(client: client, session: session)
65
+ client.with_session(@options) do |session|
66
66
  operations.each do |operation|
67
+ context = Operation::Context.new(
68
+ client: client,
69
+ session: session,
70
+ operation_timeouts: { operation_timeout_ms: op_timeout_ms(deadline) }
71
+ )
67
72
  if single_statement?(operation)
68
73
  write_concern = write_concern(session)
69
74
  write_with_retry(write_concern, context: context) do |connection, txn_num, context|
@@ -124,6 +129,9 @@ module Mongo
124
129
  @collection = collection
125
130
  @requests = requests
126
131
  @options = options || {}
132
+ if @options[:timeout_ms] && @options[:timeout_ms] < 0
133
+ raise ArgumentError, "timeout_ms options must be non-negative integer"
134
+ end
127
135
  end
128
136
 
129
137
  # Is the bulk write ordered?
@@ -162,6 +170,31 @@ module Mongo
162
170
  :update_one,
163
171
  :insert_one ].freeze
164
172
 
173
+ # @return [ Float | nil ] Deadline for the batch of operations, if set.
174
+ def calculate_deadline
175
+ timeout_ms = @options[:timeout_ms] || collection.timeout_ms
176
+ return nil if timeout_ms.nil?
177
+
178
+ if timeout_ms == 0
179
+ 0
180
+ else
181
+ Utils.monotonic_time + (timeout_ms / 1_000.0)
182
+ end
183
+ end
184
+
185
+ # @param [ Float | nil ] deadline Deadline for the batch of operations.
186
+ #
187
+ # @return [ Integer | nil ] Timeout in milliseconds for the next operation.
188
+ def op_timeout_ms(deadline)
189
+ return nil if deadline.nil?
190
+
191
+ if deadline == 0
192
+ 0
193
+ else
194
+ ((deadline - Utils.monotonic_time) * 1_000).to_i
195
+ end
196
+ end
197
+
165
198
  def single_statement?(operation)
166
199
  SINGLE_STATEMENT_OPS.include?(operation.keys.first)
167
200
  end
data/lib/mongo/client.rb CHANGED
@@ -111,6 +111,7 @@ module Mongo
111
111
  :ssl_verify_certificate,
112
112
  :ssl_verify_hostname,
113
113
  :ssl_verify_ocsp_endpoint,
114
+ :timeout_ms,
114
115
  :truncate_logs,
115
116
  :user,
116
117
  :wait_queue_timeout,
@@ -349,7 +350,8 @@ module Mongo
349
350
  # @option options [ Integer ] :server_selection_timeout The timeout in seconds
350
351
  # for selecting a server for an operation.
351
352
  # @option options [ Float ] :socket_timeout The timeout, in seconds, to
352
- # execute operations on a socket.
353
+ # execute operations on a socket. This option is deprecated, use
354
+ # :timeout_ms instead.
353
355
  # @option options [ Integer ] :srv_max_hosts The maximum number of mongoses
354
356
  # that the driver will communicate with for sharded topologies. If this
355
357
  # option is 0, then there will be no maximum number of mongoses. If the
@@ -413,11 +415,15 @@ module Mongo
413
415
  # @option options [ true, false ] :ssl_verify_hostname Whether to perform peer hostname
414
416
  # validation. This setting overrides :ssl_verify with respect to whether hostname validation
415
417
  # is performed.
418
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
419
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
420
+ # The default value is unset which means the feature is not enabled.
416
421
  # @option options [ true, false ] :truncate_logs Whether to truncate the
417
422
  # logs at the default 250 characters.
418
423
  # @option options [ String ] :user The user name.
419
424
  # @option options [ Float ] :wait_queue_timeout The time to wait, in
420
425
  # seconds, in the connection pool for a connection to be checked in.
426
+ # This option is deprecated, use :timeout_ms instead.
421
427
  # @option options [ Array<Hash> ] :wrapping_libraries Information about
422
428
  # libraries such as ODMs that are wrapping the driver, to be added to
423
429
  # metadata sent to the server. Specify the lower level libraries first.
@@ -425,7 +431,7 @@ module Mongo
425
431
  # @option options [ Hash ] :write Deprecated. Equivalent to :write_concern
426
432
  # option.
427
433
  # @option options [ Hash ] :write_concern The write concern options.
428
- # Can be :w => Integer|String, :wtimeout => Integer (in milliseconds),
434
+ # Can be :w => Integer|String, :wtimeout => Integer (in milliseconds, deprecated),
429
435
  # :j => Boolean, :fsync => Boolean.
430
436
  # @option options [ Integer ] :zlib_compression_level The Zlib compression level to use, if using compression.
431
437
  # See Ruby's Zlib module for valid levels.
@@ -934,8 +940,11 @@ module Mongo
934
940
  # See https://mongodb.com/docs/manual/reference/command/listDatabases/
935
941
  # for more information and usage.
936
942
  # @option opts [ Session ] :session The session to use.
937
- # @option options [ Object ] :comment A user-provided
943
+ # @option opts [ Object ] :comment A user-provided
938
944
  # comment to attach to this command.
945
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
946
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
947
+ # The default value is unset which means the feature is not enabled.
939
948
  #
940
949
  # @return [ Array<String> ] The names of the databases.
941
950
  #
@@ -955,7 +964,12 @@ module Mongo
955
964
  #
956
965
  # @option opts [ true, false ] :authorized_databases A flag that determines
957
966
  # which databases are returned based on user privileges when access control
958
- # is enabled
967
+ # is enabled.
968
+ # @option opts [ Object ] :comment A user-provided
969
+ # comment to attach to this command.
970
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
971
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
972
+ # The default value is unset which means the feature is not enabled.
959
973
  #
960
974
  # See https://mongodb.com/docs/manual/reference/command/listDatabases/
961
975
  # for more information and usage.
@@ -1095,7 +1109,7 @@ module Mongo
1095
1109
  return use(Database::ADMIN).watch(pipeline, options) unless database.name == Database::ADMIN
1096
1110
 
1097
1111
  view_options = options.dup
1098
- view_options[:await_data] = true if options[:max_await_time_ms]
1112
+ view_options[:cursor_type] = :tailable_await if options[:max_await_time_ms]
1099
1113
 
1100
1114
  Mongo::Collection::View::ChangeStream.new(
1101
1115
  Mongo::Collection::View.new(self["#{Database::COMMAND}.aggregate"], {}, view_options),
@@ -1185,6 +1199,22 @@ module Mongo
1185
1199
  @encrypted_fields_map ||= @options.fetch(:auto_encryption_options, {})[:encrypted_fields_map]
1186
1200
  end
1187
1201
 
1202
+ # @return [ Integer | nil ] Value of timeout_ms option if set.
1203
+ # @api private
1204
+ def timeout_ms
1205
+ @options[:timeout_ms]
1206
+ end
1207
+
1208
+ # @return [ Float | nil ] Value of timeout_ms option converted to seconds.
1209
+ # @api private
1210
+ def timeout_sec
1211
+ if timeout_ms.nil?
1212
+ nil
1213
+ else
1214
+ timeout_ms / 1_000.0
1215
+ end
1216
+ end
1217
+
1188
1218
  private
1189
1219
 
1190
1220
  # Create a new encrypter object using the client's auto encryption options
@@ -1230,6 +1260,8 @@ module Mongo
1230
1260
  # @option options [ true | false ] :implicit When no session is passed in,
1231
1261
  # whether to create an implicit session.
1232
1262
  # @option options [ Session ] :session The session to validate and return.
1263
+ # @option options [ Operation::Context | nil ] :context Context of the
1264
+ # operation the session is used for.
1233
1265
  #
1234
1266
  # @return [ Session ] A session object.
1235
1267
  #
@@ -1242,7 +1274,7 @@ module Mongo
1242
1274
  return options[:session].validate!(self)
1243
1275
  end
1244
1276
 
1245
- cluster.validate_session_support!
1277
+ cluster.validate_session_support!(timeout: timeout_sec)
1246
1278
 
1247
1279
  options = {implicit: true}.update(options)
1248
1280
 
@@ -40,6 +40,9 @@ module Mongo
40
40
  # should be hashes of TLS connection options. The options are equivalent
41
41
  # to TLS connection options of Mongo::Client.
42
42
  # @see Mongo::Client#initialize for list of TLS options.
43
+ # @option options [ Integer ] :timeout_ms The operation timeout in milliseconds.
44
+ # Must be a non-negative integer. An explicit value of 0 means infinite.
45
+ # The default value is unset which means the feature is disabled.
43
46
  #
44
47
  # @raise [ ArgumentError ] If required options are missing or incorrectly
45
48
  # formatted.
@@ -131,7 +134,7 @@ module Mongo
131
134
  # {'$and' => [{'$gt' => ['$field', 10]}, {'$lt' => ['$field', 20]}}
132
135
  # )
133
136
  # {$and: [{$gt: [<fieldpath>, <value1>]}, {$lt: [<fieldpath>, <value2>]}]
134
- # Only supported when queryType is "rangePreview" and algorithm is "RangePreview".
137
+ # Only supported when queryType is "range" and algorithm is "Range".
135
138
  # @note: The Range algorithm is experimental only. It is not intended
136
139
  # for public use. It is subject to breaking changes.
137
140
  #
@@ -143,11 +146,11 @@ module Mongo
143
146
  # @option options [ String ] :key_alt_name The alternate name for the
144
147
  # encryption key.
145
148
  # @option options [ String ] :algorithm The algorithm used to encrypt the
146
- # expression. The only allowed value is "RangePreview"
149
+ # expression. The only allowed value is "Range"
147
150
  # @option options [ Integer | nil ] :contention_factor Contention factor
148
151
  # to be applied If not provided, it defaults to a value of 0.
149
152
  # @option options [ String | nil ] query_type Query type to be applied.
150
- # The only allowed value is "rangePreview".
153
+ # The only allowed value is "range".
151
154
  #
152
155
  # @note The :key_id and :key_alt_name options are mutually exclusive. Only
153
156
  # one is required to perform explicit encryption.
@@ -194,7 +194,12 @@ module Mongo
194
194
  server_api: server.options[:server_api],
195
195
  connection_global_id: kill_spec.connection_global_id,
196
196
  }
197
- op.execute(server, context: Operation::Context.new(options: options))
197
+ if connection = kill_spec.connection
198
+ op.execute_with_connection(connection, context: Operation::Context.new(options: options))
199
+ connection.connection_pool.check_in(connection)
200
+ else
201
+ op.execute(server, context: Operation::Context.new(options: options))
202
+ end
198
203
 
199
204
  if session = kill_spec.session
200
205
  if session.implicit?
@@ -116,8 +116,12 @@ class Mongo::Cluster
116
116
  log_warn(
117
117
  "Server #{updated_desc.address.to_s} has an incorrect replica set name '#{updated_desc.replica_set_name}'; expected '#{topology.replica_set_name}'"
118
118
  )
119
- @updated_desc = ::Mongo::Server::Description.new(updated_desc.address,
120
- {}, average_round_trip_time: updated_desc.average_round_trip_time)
119
+ @updated_desc = ::Mongo::Server::Description.new(
120
+ updated_desc.address,
121
+ {},
122
+ average_round_trip_time: updated_desc.average_round_trip_time,
123
+ minimum_round_trip_time: updated_desc.minimum_round_trip_time
124
+ )
121
125
  update_server_descriptions
122
126
  end
123
127
  end
@@ -233,8 +237,12 @@ class Mongo::Cluster
233
237
  end
234
238
 
235
239
  if stale_primary?
236
- @updated_desc = ::Mongo::Server::Description.new(updated_desc.address,
237
- {}, average_round_trip_time: updated_desc.average_round_trip_time)
240
+ @updated_desc = ::Mongo::Server::Description.new(
241
+ updated_desc.address,
242
+ {},
243
+ average_round_trip_time: updated_desc.average_round_trip_time,
244
+ minimum_round_trip_time: updated_desc.minimum_round_trip_time
245
+ )
238
246
  update_server_descriptions
239
247
  check_if_has_primary
240
248
  return
@@ -270,9 +278,14 @@ class Mongo::Cluster
270
278
  servers_list.each do |server|
271
279
  if server.address != updated_desc.address
272
280
  if server.primary?
273
- server.update_description(::Mongo::Server::Description.new(
274
- server.address, {},
275
- average_round_trip_time: server.description.average_round_trip_time))
281
+ server.update_description(
282
+ ::Mongo::Server::Description.new(
283
+ server.address,
284
+ {},
285
+ average_round_trip_time: server.description.average_round_trip_time,
286
+ minimum_round_trip_time: updated_desc.minimum_round_trip_time
287
+ )
288
+ )
276
289
  end
277
290
  end
278
291
  end
@@ -211,6 +211,22 @@ module Mongo
211
211
  end
212
212
  end
213
213
 
214
+ # Compares each server address against the list of patterns.
215
+ #
216
+ # @param [ Array<String> ] patterns the URL suffixes to compare
217
+ # each server against.
218
+ #
219
+ # @return [ true | false ] whether any of the addresses match any of
220
+ # the patterns or not.
221
+ #
222
+ # @api private
223
+ def server_hosts_match_any?(patterns)
224
+ server_descriptions.any? do |addr_spec, _desc|
225
+ addr, _port = addr_spec.split(/:/)
226
+ patterns.any? { |pattern| addr.end_with?(pattern) }
227
+ end
228
+ end
229
+
214
230
  private
215
231
 
216
232
  # Validates and/or transforms options as necessary for the topology.
data/lib/mongo/cluster.rb CHANGED
@@ -157,7 +157,7 @@ module Mongo
157
157
  # @sdam_flow_lock covers just the sdam flow. Note it does not apply
158
158
  # to @topology replacements which are done under @update_lock.
159
159
  @sdam_flow_lock = Mutex.new
160
- Session::SessionPool.create(self)
160
+ @session_pool = Session::SessionPool.new(self)
161
161
 
162
162
  if seeds.empty? && load_balanced?
163
163
  raise ArgumentError, 'Load-balanced clusters with no seeds are prohibited'
@@ -186,6 +186,8 @@ module Mongo
186
186
  recreate_topology(topology, opening_topology)
187
187
  end
188
188
 
189
+ possibly_warn_about_compatibility!
190
+
189
191
  if load_balanced?
190
192
  # We are required by the specifications to produce certain SDAM events
191
193
  # when in load-balanced topology.
@@ -777,12 +779,19 @@ module Mongo
777
779
  # Deprecated and ignored.
778
780
  # @param [ Session | nil ] session Optional session to take into account
779
781
  # for mongos pinning.
782
+ # @param [ Float | nil ] :timeout Timeout in seconds for the operation,
783
+ # if any.
780
784
  #
781
785
  # @return [ Mongo::Server ] A primary server.
782
786
  #
783
787
  # @since 2.0.0
784
- def next_primary(ping = nil, session = nil)
785
- ServerSelector.primary.select_server(self, nil, session)
788
+ def next_primary(ping = nil, session = nil, timeout: nil)
789
+ ServerSelector.primary.select_server(
790
+ self,
791
+ nil,
792
+ session,
793
+ timeout: timeout
794
+ )
786
795
  end
787
796
 
788
797
  # Get the connection pool for the server.
@@ -972,8 +981,11 @@ module Mongo
972
981
  # any servers and doesn't find any servers for the duration of
973
982
  # server selection timeout.
974
983
  #
984
+ # @param [ Float | nil ] :timeout Timeout for the validation. Since the
985
+ # validation process involves server selection,
986
+ #
975
987
  # @api private
976
- def validate_session_support!
988
+ def validate_session_support!(timeout: nil)
977
989
  if topology.is_a?(Topology::LoadBalanced)
978
990
  return
979
991
  end
@@ -991,7 +1003,7 @@ module Mongo
991
1003
  # No data bearing servers known - perform server selection to try to
992
1004
  # get a response from at least one of them, to return an accurate
993
1005
  # assessment of whether sessions are currently supported.
994
- ServerSelector.get(mode: :primary_preferred).select_server(self)
1006
+ ServerSelector.get(mode: :primary_preferred).select_server(self, timeout: timeout)
995
1007
  @state_change_lock.synchronize do
996
1008
  @sdam_flow_lock.synchronize do
997
1009
  unless topology.logical_session_timeout
@@ -1082,6 +1094,30 @@ module Mongo
1082
1094
  Monitoring::Event::TopologyChanged.new(previous_topology, @topology)
1083
1095
  )
1084
1096
  end
1097
+
1098
+ COSMOSDB_HOST_PATTERNS = %w[ .cosmos.azure.com ]
1099
+ COSMOSDB_LOG_MESSAGE = 'You appear to be connected to a CosmosDB cluster. ' \
1100
+ 'For more information regarding feature compatibility and support please visit ' \
1101
+ 'https://www.mongodb.com/supportability/cosmosdb'
1102
+
1103
+ DOCUMENTDB_HOST_PATTERNS = %w[ .docdb.amazonaws.com .docdb-elastic.amazonaws.com ]
1104
+ DOCUMENTDB_LOG_MESSAGE = 'You appear to be connected to a DocumentDB cluster. ' \
1105
+ 'For more information regarding feature compatibility and support please visit ' \
1106
+ 'https://www.mongodb.com/supportability/documentdb'
1107
+
1108
+ # Compares the server hosts with address suffixes of known services
1109
+ # that provide limited MongoDB API compatibility, and warns about them.
1110
+ def possibly_warn_about_compatibility!
1111
+ if topology.server_hosts_match_any?(COSMOSDB_HOST_PATTERNS)
1112
+ log_info COSMOSDB_LOG_MESSAGE
1113
+ return
1114
+ end
1115
+
1116
+ if topology.server_hosts_match_any?(DOCUMENTDB_HOST_PATTERNS)
1117
+ log_info DOCUMENTDB_LOG_MESSAGE
1118
+ return
1119
+ end
1120
+ end
1085
1121
  end
1086
1122
  end
1087
1123
 
@@ -30,7 +30,7 @@ module Mongo
30
30
  # @return [ Result ] The result of the execution.
31
31
  def do_drop(operation, session, context)
32
32
  operation.execute(next_primary(nil, session), context: context)
33
- rescue Error::OperationFailure => ex
33
+ rescue Error::OperationFailure::Family => ex
34
34
  # NamespaceNotFound
35
35
  if ex.code == 26 || ex.code.nil? && ex.message =~ /ns not found/
36
36
  false
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongo
4
+ class Collection
5
+ class View
6
+ class Aggregation
7
+ # Distills the behavior common to aggregator classes, like
8
+ # View::Aggregator and View::ChangeStream.
9
+ module Behavior
10
+ extend Forwardable
11
+ include Enumerable
12
+ include Immutable
13
+ include Iterable
14
+ include Explainable
15
+ include Loggable
16
+ include Retryable
17
+
18
+ # @return [ View ] view The collection view.
19
+ attr_reader :view
20
+
21
+ # Delegate necessary operations to the view.
22
+ def_delegators :view, :collection, :read, :cluster, :cursor_type, :limit, :batch_size
23
+
24
+ # Delegate necessary operations to the collection.
25
+ def_delegators :collection, :database, :client
26
+
27
+ # Set to true if disk usage is allowed during the aggregation.
28
+ #
29
+ # @example Set disk usage flag.
30
+ # aggregation.allow_disk_use(true)
31
+ #
32
+ # @param [ true, false ] value The flag value.
33
+ #
34
+ # @return [ true, false, Aggregation ] The aggregation if a value was
35
+ # set or the value if used as a getter.
36
+ #
37
+ # @since 2.0.0
38
+ def allow_disk_use(value = nil)
39
+ configure(:allow_disk_use, value)
40
+ end
41
+
42
+ # Get the explain plan for the aggregation.
43
+ #
44
+ # @example Get the explain plan for the aggregation.
45
+ # aggregation.explain
46
+ #
47
+ # @return [ Hash ] The explain plan.
48
+ #
49
+ # @since 2.0.0
50
+ def explain
51
+ self.class.new(view, pipeline, options.merge(explain: true)).first
52
+ end
53
+
54
+ # Whether this aggregation will write its result to a database collection.
55
+ #
56
+ # @return [ Boolean ] Whether the aggregation will write its result
57
+ # to a collection.
58
+ #
59
+ # @api private
60
+ def write?
61
+ pipeline.any? { |op| op.key?('$out') || op.key?(:$out) || op.key?('$merge') || op.key?(:$merge) }
62
+ end
63
+
64
+ # @return [ Integer | nil ] the timeout_ms value that was passed as
65
+ # an option to this object, or which was inherited from the view.
66
+ #
67
+ # @api private
68
+ def timeout_ms
69
+ @timeout_ms || view.timeout_ms
70
+ end
71
+
72
+ private
73
+
74
+ # Common setup for all classes that include this behavior; the
75
+ # constructor should invoke this method.
76
+ def perform_setup(view, options, forbid: [])
77
+ @view = view
78
+
79
+ @timeout_ms = options.delete(:timeout_ms)
80
+ @options = BSON::Document.new(options).freeze
81
+
82
+ yield
83
+
84
+ validate_timeout_mode!(options, forbid: forbid)
85
+ end
86
+
87
+ def server_selector
88
+ @view.send(:server_selector)
89
+ end
90
+
91
+ def aggregate_spec(session, read_preference)
92
+ Builder::Aggregation.new(
93
+ pipeline,
94
+ view,
95
+ options.merge(session: session, read_preference: read_preference)
96
+ ).specification
97
+ end
98
+
99
+ # Skip, sort, limit, projection are specified as pipeline stages
100
+ # rather than as options.
101
+ def cache_options
102
+ {
103
+ namespace: collection.namespace,
104
+ selector: pipeline,
105
+ read_concern: view.read_concern,
106
+ read_preference: view.read_preference,
107
+ collation: options[:collation],
108
+ # Aggregations can read documents from more than one collection,
109
+ # so they will be cleared on every write operation.
110
+ multi_collection: true,
111
+ }
112
+ end
113
+
114
+ # @return [ Hash ] timeout_ms value set on the operation level (if any),
115
+ # and/or timeout_ms that is set on collection/database/client level (if any).
116
+ #
117
+ # @api private
118
+ def operation_timeouts(opts = {})
119
+ {}.tap do |result|
120
+ if opts[:timeout_ms] || @timeout_ms
121
+ result[:operation_timeout_ms] = opts.delete(:timeout_ms) || @timeout_ms
122
+ else
123
+ result[:inherited_timeout_ms] = view.timeout_ms
124
+ end
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end