mongo 2.19.1 → 2.21.0

Sign up to get free protection for your applications and to get access to all the features.
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