mongo 2.14.0 → 2.15.0.alpha

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 (230) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/README.md +4 -1
  5. data/Rakefile +8 -15
  6. data/lib/mongo.rb +23 -0
  7. data/lib/mongo/auth/aws/conversation.rb +1 -4
  8. data/lib/mongo/auth/base.rb +13 -7
  9. data/lib/mongo/auth/conversation_base.rb +32 -0
  10. data/lib/mongo/auth/cr/conversation.rb +6 -29
  11. data/lib/mongo/auth/gssapi/conversation.rb +4 -15
  12. data/lib/mongo/auth/ldap/conversation.rb +3 -14
  13. data/lib/mongo/auth/sasl_conversation_base.rb +1 -13
  14. data/lib/mongo/auth/scram_conversation_base.rb +7 -34
  15. data/lib/mongo/auth/user/view.rb +16 -9
  16. data/lib/mongo/auth/x509/conversation.rb +4 -25
  17. data/lib/mongo/background_thread.rb +11 -0
  18. data/lib/mongo/bulk_write.rb +21 -18
  19. data/lib/mongo/client.rb +82 -6
  20. data/lib/mongo/cluster.rb +19 -28
  21. data/lib/mongo/cluster/reapers/cursor_reaper.rb +6 -2
  22. data/lib/mongo/cluster/sdam_flow.rb +14 -0
  23. data/lib/mongo/collection.rb +8 -6
  24. data/lib/mongo/collection/view/aggregation.rb +1 -1
  25. data/lib/mongo/collection/view/change_stream.rb +1 -1
  26. data/lib/mongo/collection/view/iterable.rb +1 -1
  27. data/lib/mongo/collection/view/map_reduce.rb +2 -2
  28. data/lib/mongo/collection/view/readable.rb +42 -20
  29. data/lib/mongo/collection/view/writable.rb +14 -14
  30. data/lib/mongo/cursor.rb +2 -2
  31. data/lib/mongo/database.rb +22 -5
  32. data/lib/mongo/database/view.rb +1 -1
  33. data/lib/mongo/error.rb +9 -1
  34. data/lib/mongo/error/bulk_write_error.rb +17 -3
  35. data/lib/mongo/error/internal_driver_error.rb +22 -0
  36. data/lib/mongo/error/operation_failure.rb +21 -2
  37. data/lib/mongo/error/parser.rb +65 -12
  38. data/lib/mongo/error/server_api_conflict.rb +23 -0
  39. data/lib/mongo/error/server_api_not_supported.rb +24 -0
  40. data/lib/mongo/error/unmet_dependency.rb +21 -0
  41. data/lib/mongo/grid/fs_bucket.rb +37 -37
  42. data/lib/mongo/index/view.rb +21 -11
  43. data/lib/mongo/monitoring.rb +13 -4
  44. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +27 -16
  45. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +26 -15
  46. data/lib/mongo/operation.rb +2 -2
  47. data/lib/mongo/operation/collections_info.rb +18 -1
  48. data/lib/mongo/operation/collections_info/command.rb +2 -2
  49. data/lib/mongo/operation/context.rb +99 -0
  50. data/lib/mongo/operation/indexes.rb +15 -1
  51. data/lib/mongo/operation/insert/command.rb +2 -2
  52. data/lib/mongo/operation/insert/legacy.rb +2 -2
  53. data/lib/mongo/operation/insert/op_msg.rb +2 -2
  54. data/lib/mongo/operation/list_collections/result.rb +4 -1
  55. data/lib/mongo/operation/result.rb +2 -0
  56. data/lib/mongo/operation/shared/executable.rb +24 -14
  57. data/lib/mongo/operation/shared/executable_no_validate.rb +2 -2
  58. data/lib/mongo/operation/shared/op_msg_or_command.rb +1 -7
  59. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +1 -7
  60. data/lib/mongo/operation/shared/polymorphic_operation.rb +39 -0
  61. data/lib/mongo/operation/shared/response_handling.rb +23 -23
  62. data/lib/mongo/operation/shared/sessions_supported.rb +13 -2
  63. data/lib/mongo/operation/shared/write.rb +8 -18
  64. data/lib/mongo/protocol/compressed.rb +51 -5
  65. data/lib/mongo/protocol/message.rb +20 -2
  66. data/lib/mongo/protocol/msg.rb +36 -11
  67. data/lib/mongo/query_cache.rb +30 -0
  68. data/lib/mongo/retryable.rb +1 -1
  69. data/lib/mongo/server.rb +7 -15
  70. data/lib/mongo/server/app_metadata.rb +52 -18
  71. data/lib/mongo/server/connection.rb +5 -0
  72. data/lib/mongo/server/connection_base.rb +13 -10
  73. data/lib/mongo/server/connection_pool.rb +6 -4
  74. data/lib/mongo/server/description.rb +4 -0
  75. data/lib/mongo/server/description/features.rb +9 -8
  76. data/lib/mongo/server/monitor.rb +20 -1
  77. data/lib/mongo/server/monitor/app_metadata.rb +1 -1
  78. data/lib/mongo/server/monitor/connection.rb +9 -10
  79. data/lib/mongo/server/pending_connection.rb +24 -6
  80. data/lib/mongo/server/push_monitor.rb +11 -1
  81. data/lib/mongo/session.rb +2 -2
  82. data/lib/mongo/session/session_pool.rb +4 -2
  83. data/lib/mongo/socket.rb +29 -4
  84. data/lib/mongo/socket/ssl.rb +8 -0
  85. data/lib/mongo/srv/monitor.rb +0 -11
  86. data/lib/mongo/uri/options_mapper.rb +38 -0
  87. data/lib/mongo/utils.rb +15 -0
  88. data/lib/mongo/version.rb +1 -1
  89. data/spec/README.md +24 -1
  90. data/spec/integration/auth_spec.rb +25 -15
  91. data/spec/integration/bulk_write_error_message_spec.rb +41 -0
  92. data/spec/integration/change_stream_spec.rb +4 -4
  93. data/spec/integration/command_monitoring_spec.rb +2 -2
  94. data/spec/integration/connection_spec.rb +2 -0
  95. data/spec/integration/docs_examples_spec.rb +8 -1
  96. data/spec/integration/fork_reconnect_spec.rb +4 -1
  97. data/spec/integration/ocsp_verifier_spec.rb +13 -7
  98. data/spec/integration/operation_failure_code_spec.rb +1 -1
  99. data/spec/integration/operation_failure_message_spec.rb +90 -0
  100. data/spec/integration/reconnect_spec.rb +1 -1
  101. data/spec/integration/sdam_error_handling_spec.rb +1 -1
  102. data/spec/integration/sdam_events_spec.rb +3 -5
  103. data/spec/integration/snappy_compression_spec.rb +25 -0
  104. data/spec/integration/srv_monitoring_spec.rb +1 -1
  105. data/spec/integration/transactions_examples_spec.rb +6 -0
  106. data/spec/integration/zlib_compression_spec.rb +1 -1
  107. data/spec/integration/zstd_compression_spec.rb +26 -0
  108. data/spec/lite_spec_helper.rb +7 -1
  109. data/spec/mongo/address_spec.rb +15 -11
  110. data/spec/mongo/auth/ldap/conversation_spec.rb +1 -1
  111. data/spec/mongo/auth/ldap_spec.rb +5 -1
  112. data/spec/mongo/auth/scram_negotiation_spec.rb +1 -1
  113. data/spec/mongo/auth/scram_spec.rb +1 -1
  114. data/spec/mongo/auth/x509/conversation_spec.rb +3 -3
  115. data/spec/mongo/client_construction_spec.rb +207 -33
  116. data/spec/mongo/client_spec.rb +17 -0
  117. data/spec/mongo/cluster_spec.rb +3 -18
  118. data/spec/mongo/collection/view/explainable_spec.rb +1 -1
  119. data/spec/mongo/collection/view/readable_spec.rb +33 -19
  120. data/spec/mongo/collection_crud_spec.rb +4357 -0
  121. data/spec/mongo/collection_ddl_spec.rb +534 -0
  122. data/spec/mongo/collection_spec.rb +5 -4859
  123. data/spec/mongo/database_spec.rb +66 -4
  124. data/spec/mongo/error/bulk_write_error_spec.rb +3 -3
  125. data/spec/mongo/error/parser_spec.rb +37 -6
  126. data/spec/mongo/index/view_spec.rb +8 -2
  127. data/spec/mongo/monitoring/event/server_heartbeat_failed_spec.rb +1 -1
  128. data/spec/mongo/monitoring/event/server_heartbeat_succeeded_spec.rb +1 -1
  129. data/spec/mongo/operation/aggregate_spec.rb +2 -1
  130. data/spec/mongo/operation/collections_info_spec.rb +4 -1
  131. data/spec/mongo/operation/command_spec.rb +6 -3
  132. data/spec/mongo/operation/create_index_spec.rb +6 -3
  133. data/spec/mongo/operation/create_user_spec.rb +6 -3
  134. data/spec/mongo/operation/delete/bulk_spec.rb +9 -6
  135. data/spec/mongo/operation/delete_spec.rb +11 -7
  136. data/spec/mongo/operation/drop_index_spec.rb +6 -2
  137. data/spec/mongo/operation/find/legacy_spec.rb +3 -1
  138. data/spec/mongo/operation/get_more_spec.rb +3 -1
  139. data/spec/mongo/operation/indexes_spec.rb +5 -1
  140. data/spec/mongo/operation/insert/bulk_spec.rb +10 -7
  141. data/spec/mongo/operation/insert_spec.rb +15 -12
  142. data/spec/mongo/operation/map_reduce_spec.rb +5 -2
  143. data/spec/mongo/operation/remove_user_spec.rb +6 -3
  144. data/spec/mongo/operation/result_spec.rb +1 -1
  145. data/spec/mongo/operation/update/bulk_spec.rb +9 -6
  146. data/spec/mongo/operation/update_spec.rb +10 -7
  147. data/spec/mongo/operation/update_user_spec.rb +4 -1
  148. data/spec/mongo/protocol/compressed_spec.rb +26 -12
  149. data/spec/mongo/query_cache_middleware_spec.rb +55 -0
  150. data/spec/mongo/retryable_spec.rb +3 -2
  151. data/spec/mongo/server/app_metadata_spec.rb +2 -0
  152. data/spec/mongo/server/connection_pool/populator_spec.rb +3 -1
  153. data/spec/mongo/server/connection_pool_spec.rb +1 -1
  154. data/spec/mongo/server/connection_spec.rb +24 -17
  155. data/spec/mongo/server/monitor/connection_spec.rb +17 -7
  156. data/spec/mongo/server/monitor_spec.rb +9 -1
  157. data/spec/mongo/server_spec.rb +15 -2
  158. data/spec/mongo/socket/ssl_spec.rb +40 -0
  159. data/spec/mongo/socket_spec.rb +2 -2
  160. data/spec/mongo/tls_context_hooks_spec.rb +37 -0
  161. data/spec/runners/connection_string.rb +0 -4
  162. data/spec/runners/crud/requirement.rb +40 -3
  163. data/spec/runners/crud/verifier.rb +8 -0
  164. data/spec/runners/transactions/operation.rb +13 -2
  165. data/spec/runners/transactions/test.rb +1 -0
  166. data/spec/runners/unified.rb +96 -0
  167. data/spec/runners/unified/assertions.rb +249 -0
  168. data/spec/runners/unified/change_stream_operations.rb +26 -0
  169. data/spec/runners/unified/crud_operations.rb +199 -0
  170. data/spec/runners/unified/ddl_operations.rb +96 -0
  171. data/spec/runners/unified/entity_map.rb +39 -0
  172. data/spec/runners/unified/error.rb +25 -0
  173. data/spec/runners/unified/event_subscriber.rb +91 -0
  174. data/spec/runners/unified/exceptions.rb +21 -0
  175. data/spec/runners/unified/grid_fs_operations.rb +55 -0
  176. data/spec/runners/unified/support_operations.rb +250 -0
  177. data/spec/runners/unified/test.rb +393 -0
  178. data/spec/runners/unified/test_group.rb +28 -0
  179. data/spec/runners/unified/using_hash.rb +31 -0
  180. data/spec/shared/bin/get-mongodb-download-url +17 -0
  181. data/spec/shared/lib/mrss/cluster_config.rb +218 -0
  182. data/spec/shared/lib/mrss/constraints.rb +43 -0
  183. data/spec/shared/lib/mrss/docker_runner.rb +262 -0
  184. data/spec/shared/lib/mrss/server_version_registry.rb +112 -0
  185. data/spec/shared/lib/mrss/utils.rb +15 -0
  186. data/spec/shared/share/Dockerfile.erb +231 -0
  187. data/spec/shared/shlib/distro.sh +73 -0
  188. data/spec/shared/shlib/server.sh +290 -0
  189. data/spec/shared/shlib/set_env.sh +128 -0
  190. data/spec/solo/clean_exit_spec.rb +21 -0
  191. data/spec/spec_helper.rb +4 -1
  192. data/spec/spec_tests/crud_unified_spec.rb +10 -0
  193. data/spec/spec_tests/data/change_streams/change-streams.yml +0 -1
  194. data/spec/spec_tests/data/crud_unified/estimatedDocumentCount.yml +267 -0
  195. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-4.9.yml +60 -0
  196. data/spec/spec_tests/data/retryable_reads/{estimatedDocumentCount.yml → estimatedDocumentCount-pre4.9.yml} +2 -0
  197. data/spec/spec_tests/data/retryable_reads/estimatedDocumentCount-serverErrors-4.9.yml +146 -0
  198. data/spec/spec_tests/data/retryable_reads/{estimatedDocumentCount-serverErrors.yml → estimatedDocumentCount-serverErrors-pre4.9.yml} +2 -0
  199. data/spec/spec_tests/data/retryable_reads/listIndexNames.yml +1 -1
  200. data/spec/spec_tests/data/unified/valid-fail/operation-failure.yml +31 -0
  201. data/spec/spec_tests/data/unified/valid-pass/poc-change-streams.yml +220 -0
  202. data/spec/spec_tests/data/unified/valid-pass/poc-command-monitoring.yml +102 -0
  203. data/spec/spec_tests/data/unified/valid-pass/poc-crud.yml +184 -0
  204. data/spec/spec_tests/data/unified/valid-pass/poc-gridfs.yml +155 -0
  205. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-reads.yml +193 -0
  206. data/spec/spec_tests/data/unified/valid-pass/poc-retryable-writes.yml +210 -0
  207. data/spec/spec_tests/data/unified/valid-pass/poc-sessions.yml +215 -0
  208. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-convenient-api.yml +235 -0
  209. data/spec/spec_tests/data/unified/valid-pass/poc-transactions-mongos-pin-auto.yml +169 -0
  210. data/spec/spec_tests/data/unified/valid-pass/poc-transactions.yml +170 -0
  211. data/spec/spec_tests/data/uri_options/compression-options.yml +1 -1
  212. data/spec/spec_tests/data/versioned_api/crud-api-version-1-strict.yml +416 -0
  213. data/spec/spec_tests/data/versioned_api/crud-api-version-1.yml +409 -0
  214. data/spec/spec_tests/data/versioned_api/runcommand-helper-no-api-version-declared.yml +67 -0
  215. data/spec/spec_tests/data/versioned_api/test-commands-deprecation-errors.yml +47 -0
  216. data/spec/spec_tests/data/versioned_api/test-commands-strict-mode.yml +44 -0
  217. data/spec/spec_tests/data/versioned_api/transaction-handling.yml +180 -0
  218. data/spec/spec_tests/unified_spec.rb +15 -0
  219. data/spec/spec_tests/uri_options_spec.rb +16 -0
  220. data/spec/spec_tests/versioned_api_spec.rb +10 -0
  221. data/spec/support/common_shortcuts.rb +15 -1
  222. data/spec/support/shared/session.rb +2 -2
  223. data/spec/support/spec_config.rb +46 -3
  224. data/spec/support/spec_setup.rb +48 -38
  225. data/spec/support/utils.rb +64 -3
  226. metadata +1104 -992
  227. metadata.gz.sig +0 -0
  228. data/lib/mongo/operation/shared/collections_info_or_list_collections.rb +0 -58
  229. data/lib/mongo/operation/shared/op_msg_or_list_indexes_command.rb +0 -47
  230. data/spec/support/cluster_config.rb +0 -207
@@ -307,9 +307,9 @@ module Mongo
307
307
  # @api private
308
308
  def publish_heartbeat(server, awaited: false)
309
309
  if monitoring?
310
- event = Event::ServerHeartbeatStarted.new(
310
+ started_event = Event::ServerHeartbeatStarted.new(
311
311
  server.address, awaited: awaited)
312
- started(SERVER_HEARTBEAT, event)
312
+ started(SERVER_HEARTBEAT, started_event)
313
313
  end
314
314
 
315
315
  # The duration we publish in heartbeat succeeded/failed events is
@@ -328,14 +328,23 @@ module Mongo
328
328
  rescue => exc
329
329
  if monitoring?
330
330
  event = Event::ServerHeartbeatFailed.new(
331
- server.address, Time.now-start_time, exc, awaited: awaited)
331
+ server.address,
332
+ Time.now-start_time,
333
+ exc,
334
+ awaited: awaited,
335
+ started_event: started_event,
336
+ )
332
337
  failed(SERVER_HEARTBEAT, event)
333
338
  end
334
339
  raise
335
340
  else
336
341
  if monitoring?
337
342
  event = Event::ServerHeartbeatSucceeded.new(
338
- server.address, Time.now-start_time, awaited: awaited)
343
+ server.address,
344
+ Time.now-start_time,
345
+ awaited: awaited,
346
+ started_event: started_event,
347
+ )
339
348
  succeeded(SERVER_HEARTBEAT, event)
340
349
  end
341
350
  result
@@ -21,6 +21,29 @@ module Mongo
21
21
  # @since 2.7.0
22
22
  class ServerHeartbeatFailed < Mongo::Event::Base
23
23
 
24
+ # Create the event.
25
+ #
26
+ # @example Create the event.
27
+ # ServerHeartbeatSucceeded.new(address, duration)
28
+ #
29
+ # @param [ Address ] address The server address.
30
+ # @param [ Float ] round_trip_time Duration of ismaster call in seconds.
31
+ # @param [ true | false ] awaited Whether the heartbeat was awaited.
32
+ # @param [ Monitoring::Event::ServerHeartbeatStarted ] started_event
33
+ # The corresponding started event.
34
+ #
35
+ # @since 2.7.0
36
+ # @api private
37
+ def initialize(address, round_trip_time, error, awaited: false,
38
+ started_event:
39
+ )
40
+ @address = address
41
+ @round_trip_time = round_trip_time
42
+ @error = error
43
+ @awaited = !!awaited
44
+ @started_event = started_event
45
+ end
46
+
24
47
  # @return [ Address ] address The server address.
25
48
  attr_reader :address
26
49
 
@@ -41,23 +64,11 @@ module Mongo
41
64
  @awaited
42
65
  end
43
66
 
44
- # Create the event.
45
- #
46
- # @example Create the event.
47
- # ServerHeartbeatSucceeded.new(address, duration)
48
- #
49
- # @param [ Address ] address The server address.
50
- # @param [ Float ] round_trip_time Duration of ismaster call in seconds.
51
- # @param [ true | false ] awaited Whether the heartbeat was awaited.
67
+ # @return [ Monitoring::Event::ServerHeartbeatStarted ]
68
+ # The corresponding started event.
52
69
  #
53
- # @since 2.7.0
54
- # @api private
55
- def initialize(address, round_trip_time, error, awaited: false)
56
- @address = address
57
- @round_trip_time = round_trip_time
58
- @error = error
59
- @awaited = !!awaited
60
- end
70
+ # @api experimental
71
+ attr_reader :started_event
61
72
 
62
73
  # Returns a concise yet useful summary of the event.
63
74
  #
@@ -21,20 +21,6 @@ module Mongo
21
21
  # @since 2.7.0
22
22
  class ServerHeartbeatSucceeded < Mongo::Event::Base
23
23
 
24
- # @return [ Address ] address The server address.
25
- attr_reader :address
26
-
27
- # @return [ Float ] round_trip_time Duration of ismaster call in seconds.
28
- attr_reader :round_trip_time
29
-
30
- # Alias of round_trip_time.
31
- alias :duration :round_trip_time
32
-
33
- # @return [ true | false ] Whether the heartbeat was awaited.
34
- def awaited?
35
- @awaited
36
- end
37
-
38
24
  # Create the event.
39
25
  #
40
26
  # @example Create the event.
@@ -43,15 +29,40 @@ module Mongo
43
29
  # @param [ Address ] address The server address.
44
30
  # @param [ Float ] round_trip_time Duration of ismaster call in seconds.
45
31
  # @param [ true | false ] awaited Whether the heartbeat was awaited.
32
+ # @param [ Monitoring::Event::ServerHeartbeatStarted ] started_event
33
+ # The corresponding started event.
46
34
  #
47
35
  # @since 2.7.0
48
36
  # @api private
49
- def initialize(address, round_trip_time, awaited: false)
37
+ def initialize(address, round_trip_time, awaited: false,
38
+ started_event:
39
+ )
50
40
  @address = address
51
41
  @round_trip_time = round_trip_time
52
42
  @awaited = !!awaited
43
+ @started_event = started_event
53
44
  end
54
45
 
46
+ # @return [ Address ] address The server address.
47
+ attr_reader :address
48
+
49
+ # @return [ Float ] round_trip_time Duration of ismaster call in seconds.
50
+ attr_reader :round_trip_time
51
+
52
+ # Alias of round_trip_time.
53
+ alias :duration :round_trip_time
54
+
55
+ # @return [ true | false ] Whether the heartbeat was awaited.
56
+ def awaited?
57
+ @awaited
58
+ end
59
+
60
+ # @return [ Monitoring::Event::ServerHeartbeatStarted ]
61
+ # The corresponding started event.
62
+ #
63
+ # @api experimental
64
+ attr_reader :started_event
65
+
55
66
  # Returns a concise yet useful summary of the event.
56
67
  #
57
68
  # @return [ String ] String summary of the event.
@@ -1,3 +1,4 @@
1
+ require 'mongo/operation/context'
1
2
  require 'mongo/operation/result'
2
3
 
3
4
  require 'mongo/operation/shared/response_handling'
@@ -5,6 +6,7 @@ require 'mongo/operation/shared/executable'
5
6
  require 'mongo/operation/shared/executable_no_validate'
6
7
  require 'mongo/operation/shared/executable_transaction_label'
7
8
  require 'mongo/operation/shared/polymorphic_lookup'
9
+ require 'mongo/operation/shared/polymorphic_operation'
8
10
  require 'mongo/operation/shared/polymorphic_result'
9
11
  require 'mongo/operation/shared/read_preference_supported'
10
12
  require 'mongo/operation/shared/bypass_document_validation'
@@ -18,8 +20,6 @@ require 'mongo/operation/shared/specifiable'
18
20
  require 'mongo/operation/shared/object_id_generator'
19
21
  require 'mongo/operation/shared/op_msg_or_command'
20
22
  require 'mongo/operation/shared/op_msg_or_find_command'
21
- require 'mongo/operation/shared/op_msg_or_list_indexes_command'
22
- require 'mongo/operation/shared/collections_info_or_list_collections'
23
23
 
24
24
  require 'mongo/operation/op_msg_base'
25
25
  require 'mongo/operation/command'
@@ -25,7 +25,24 @@ module Mongo
25
25
  # @since 2.0.0
26
26
  class CollectionsInfo
27
27
  include Specifiable
28
- include CollectionsInfoOrListCollections
28
+ include PolymorphicOperation
29
+ include PolymorphicLookup
30
+
31
+ private
32
+
33
+ def final_operation(connection)
34
+ op_class = if connection.features.list_collections_enabled?
35
+ if connection.features.op_msg_enabled?
36
+ ListCollections::OpMsg
37
+ else
38
+ ListCollections::Command
39
+ end
40
+ else
41
+ CollectionsInfo::Command
42
+ end
43
+
44
+ op_class.new(spec)
45
+ end
29
46
  end
30
47
  end
31
48
  end
@@ -27,9 +27,9 @@ module Mongo
27
27
 
28
28
  private
29
29
 
30
- def get_result(connection, client, options = {})
30
+ def get_result(connection, context, options = {})
31
31
  # This is a Mongo::Operation::CollectionsInfo::Result
32
- Result.new(*dispatch_message(connection, client), db_name)
32
+ Result.new(*dispatch_message(connection, context), db_name)
33
33
  end
34
34
 
35
35
  def selector(connection)
@@ -0,0 +1,99 @@
1
+ # Copyright (C) 2021 MongoDB Inc.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ module Mongo
16
+ module Operation
17
+
18
+ # Context for operations.
19
+ #
20
+ # Holds various objects needed to make decisions about operation execution
21
+ # in a single container, and provides facade methods for the contained
22
+ # objects.
23
+ #
24
+ # @api private
25
+ class Context
26
+ def initialize(client: nil, session: nil, options: nil)
27
+ if options
28
+ if client
29
+ raise ArgumentError, 'Client and options cannot both be specified'
30
+ end
31
+
32
+ if session
33
+ raise ArgumentError, 'Session and options cannot both be specified'
34
+ end
35
+ end
36
+
37
+ @client = client
38
+ @session = session
39
+ @options = options
40
+ end
41
+
42
+ attr_reader :client
43
+ attr_reader :session
44
+ attr_reader :options
45
+
46
+ def in_transaction?
47
+ session&.in_transaction? || false
48
+ end
49
+
50
+ def starting_transaction?
51
+ session&.starting_transaction? || false
52
+ end
53
+
54
+ def committing_transaction?
55
+ in_transaction? && session.committing_transaction?
56
+ end
57
+
58
+ def aborting_transaction?
59
+ in_transaction? && session.aborting_transaction?
60
+ end
61
+
62
+ def modern_retry_writes?
63
+ client && client.options[:retry_writes]
64
+ end
65
+
66
+ def legacy_retry_writes?
67
+ client && !client.options[:retry_writes] && client.max_write_retries > 0
68
+ end
69
+
70
+ def any_retry_writes?
71
+ modern_retry_writes? || legacy_retry_writes?
72
+ end
73
+
74
+ def server_api
75
+ if client
76
+ client.options[:server_api]
77
+ elsif options
78
+ options[:server_api]
79
+ end
80
+ end
81
+
82
+ def encrypt?
83
+ client&.encrypter&.encrypt? || false
84
+ end
85
+
86
+ def decrypt?
87
+ !!client&.encrypter
88
+ end
89
+
90
+ def encrypter
91
+ if client&.encrypter
92
+ client.encrypter
93
+ else
94
+ raise Error::InternalDriverError, 'Encrypter should only be accessed when encryption is to be performed'
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -27,7 +27,21 @@ module Mongo
27
27
  # @since 2.0.0
28
28
  class Indexes
29
29
  include Specifiable
30
- include OpMsgOrListIndexesCommand
30
+ include PolymorphicOperation
31
+ include PolymorphicLookup
32
+
33
+ private
34
+
35
+ def final_operation(connection)
36
+ cls = if connection.features.op_msg_enabled?
37
+ polymorphic_class(self.class.name, :OpMsg)
38
+ elsif connection.features.list_indexes_enabled?
39
+ polymorphic_class(self.class.name, :Command)
40
+ else
41
+ polymorphic_class(self.class.name, :Legacy)
42
+ end
43
+ cls.new(spec)
44
+ end
31
45
  end
32
46
  end
33
47
  end
@@ -32,9 +32,9 @@ module Mongo
32
32
 
33
33
  private
34
34
 
35
- def get_result(connection, client, options = {})
35
+ def get_result(connection, context, options = {})
36
36
  # This is a Mongo::Operation::Insert::Result
37
- Result.new(*dispatch_message(connection, client), @ids)
37
+ Result.new(*dispatch_message(connection, context), @ids)
38
38
  end
39
39
 
40
40
  def selector(connection)
@@ -30,9 +30,9 @@ module Mongo
30
30
 
31
31
  private
32
32
 
33
- def get_result(connection, client, options = {})
33
+ def get_result(connection, context, options = {})
34
34
  # This is a Mongo::Operation::Insert::Result
35
- Result.new(*dispatch_message(connection, client), @ids)
35
+ Result.new(*dispatch_message(connection, context), @ids)
36
36
  end
37
37
 
38
38
  def selector
@@ -30,9 +30,9 @@ module Mongo
30
30
 
31
31
  private
32
32
 
33
- def get_result(connection, client, options = {})
33
+ def get_result(connection, context, options = {})
34
34
  # This is a Mongo::Operation::Insert::Result
35
- Result.new(*dispatch_message(connection, client), @ids)
35
+ Result.new(*dispatch_message(connection, context), @ids)
36
36
  end
37
37
 
38
38
  def selector(connection)
@@ -88,7 +88,10 @@ module Mongo
88
88
  code: parser.code,
89
89
  code_name: parser.code_name,
90
90
  labels: parser.labels,
91
- wtimeout: parser.wtimeout)
91
+ wtimeout: parser.wtimeout,
92
+ document: parser.document,
93
+ server_message: parser.server_message,
94
+ )
92
95
  end
93
96
  end
94
97
 
@@ -332,6 +332,8 @@ module Mongo
332
332
  labels: parser.labels,
333
333
  wtimeout: parser.wtimeout,
334
334
  connection_description: connection_description,
335
+ document: parser.document,
336
+ server_message: parser.server_message,
335
337
  )
336
338
  end
337
339
 
@@ -23,11 +23,11 @@ module Mongo
23
23
 
24
24
  include ResponseHandling
25
25
 
26
- def do_execute(connection, client, options = {})
26
+ def do_execute(connection, context, options = {})
27
27
  unpin_maybe(session) do
28
- add_error_labels(client, connection, session) do
28
+ add_error_labels(connection, context) do
29
29
  add_server_diagnostics(connection) do
30
- get_result(connection, client, options).tap do |result|
30
+ get_result(connection, context, options).tap do |result|
31
31
  process_result(result, connection)
32
32
  end
33
33
  end
@@ -35,15 +35,15 @@ module Mongo
35
35
  end
36
36
  end
37
37
 
38
- def execute(connection, client:, options: {})
38
+ def execute(connection, context:, options: {})
39
39
  if Lint.enabled?
40
40
  unless connection.is_a?(Mongo::Server::Connection)
41
41
  raise Error::LintError, "Connection argument is of wrong type: #{connection}"
42
42
  end
43
43
  end
44
44
 
45
- do_execute(connection, client, options).tap do |result|
46
- validate_result(result, client, connection)
45
+ do_execute(connection, context, options).tap do |result|
46
+ validate_result(result, connection, context)
47
47
  end
48
48
  end
49
49
 
@@ -53,20 +53,30 @@ module Mongo
53
53
  Result
54
54
  end
55
55
 
56
- def get_result(connection, client, options = {})
57
- result_class.new(*dispatch_message(connection, client, options))
56
+ def get_result(connection, context, options = {})
57
+ result_class.new(*dispatch_message(connection, context, options))
58
58
  end
59
59
 
60
60
  # Returns a Protocol::Message or nil as reply.
61
- def dispatch_message(connection, client, options = {})
62
- message = build_message(connection)
63
- message = message.maybe_encrypt(connection, client)
64
- reply = connection.dispatch([ message ], operation_id, client, options)
61
+ def dispatch_message(connection, context, options = {})
62
+ message = build_message(connection, context)
63
+ message = message.maybe_encrypt(connection, context)
64
+ reply = connection.dispatch([ message ], context, options)
65
65
  [reply, connection.description]
66
66
  end
67
67
 
68
- def build_message(connection)
69
- message(connection)
68
+ # @param [ Mongo::Server::Connection ] connection The connection on which
69
+ # the operation is performed.
70
+ # @param [ Mongo::Operation::Context ] context The operation context.
71
+ def build_message(connection, context)
72
+ msg = message(connection)
73
+ if (server_api = context.server_api) &&
74
+ # Commands in a transaction do not allow API parameters.
75
+ !(context.in_transaction? && !context.starting_transaction?)
76
+ then
77
+ msg = msg.maybe_add_server_api(server_api)
78
+ end
79
+ msg
70
80
  end
71
81
 
72
82
  def process_result(result, connection)