mongo 2.24.1 → 2.26.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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/bin/mongo_console +2 -2
  3. data/lib/mongo/address/validator.rb +1 -1
  4. data/lib/mongo/address.rb +1 -3
  5. data/lib/mongo/auth/aws/conversation.rb +0 -4
  6. data/lib/mongo/auth/aws/credentials_retriever.rb +3 -8
  7. data/lib/mongo/auth/base.rb +1 -1
  8. data/lib/mongo/auth/sasl_conversation_base.rb +1 -1
  9. data/lib/mongo/auth/scram_conversation_base.rb +1 -8
  10. data/lib/mongo/auth/stringprep.rb +1 -6
  11. data/lib/mongo/auth/user/view.rb +1 -1
  12. data/lib/mongo/bulk_write/combineable.rb +0 -7
  13. data/lib/mongo/bulk_write/result_combiner.rb +3 -3
  14. data/lib/mongo/bulk_write/validatable.rb +0 -4
  15. data/lib/mongo/bulk_write.rb +1 -35
  16. data/lib/mongo/client.rb +117 -17
  17. data/lib/mongo/client_encryption.rb +36 -11
  18. data/lib/mongo/cluster/reapers/cursor_reaper.rb +12 -5
  19. data/lib/mongo/cluster/sdam_flow.rb +4 -4
  20. data/lib/mongo/cluster/topology/base.rb +1 -1
  21. data/lib/mongo/cluster.rb +13 -30
  22. data/lib/mongo/collection/queryable_encryption.rb +7 -6
  23. data/lib/mongo/collection/view/aggregation/behavior.rb +1 -1
  24. data/lib/mongo/collection/view/aggregation.rb +2 -4
  25. data/lib/mongo/collection/view/builder/aggregation.rb +3 -5
  26. data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
  27. data/lib/mongo/collection/view/change_stream.rb +14 -9
  28. data/lib/mongo/collection/view/map_reduce.rb +2 -11
  29. data/lib/mongo/collection/view/readable.rb +11 -7
  30. data/lib/mongo/collection/view/writable.rb +4 -39
  31. data/lib/mongo/collection/view.rb +8 -4
  32. data/lib/mongo/collection.rb +1 -1
  33. data/lib/mongo/crypt/auto_encrypter.rb +6 -2
  34. data/lib/mongo/crypt/binary.rb +7 -4
  35. data/lib/mongo/crypt/binding.rb +154 -11
  36. data/lib/mongo/crypt/context.rb +50 -19
  37. data/lib/mongo/crypt/encryption_io.rb +11 -5
  38. data/lib/mongo/crypt/explicit_encrypter.rb +27 -12
  39. data/lib/mongo/crypt/explicit_encryption_context.rb +51 -12
  40. data/lib/mongo/crypt/handle.rb +35 -5
  41. data/lib/mongo/crypt/kms/credentials.rb +70 -31
  42. data/lib/mongo/crypt/kms/kmip/master_document.rb +30 -1
  43. data/lib/mongo/crypt/kms/master_key_document.rb +11 -6
  44. data/lib/mongo/crypt/kms.rb +12 -1
  45. data/lib/mongo/cursor.rb +8 -2
  46. data/lib/mongo/database/cursor_command_view.rb +95 -0
  47. data/lib/mongo/database.rb +144 -18
  48. data/lib/mongo/error/invalid_uri.rb +5 -1
  49. data/lib/mongo/error/operation_failure.rb +2 -2
  50. data/lib/mongo/error/parser.rb +3 -3
  51. data/lib/mongo/error/sdam_error_detection.rb +2 -3
  52. data/lib/mongo/error/unsupported_option.rb +0 -40
  53. data/lib/mongo/grid/fs_bucket.rb +29 -23
  54. data/lib/mongo/grid/stream/read.rb +2 -2
  55. data/lib/mongo/grid/stream/write.rb +3 -3
  56. data/lib/mongo/index/view.rb +13 -7
  57. data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -0
  58. data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +1 -0
  59. data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +1 -0
  60. data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +1 -0
  61. data/lib/mongo/monitoring/event/cmap/connection_closed.rb +1 -0
  62. data/lib/mongo/monitoring/event/cmap/connection_created.rb +1 -0
  63. data/lib/mongo/monitoring/event/cmap/connection_ready.rb +1 -0
  64. data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +1 -0
  65. data/lib/mongo/monitoring/event/cmap/pool_closed.rb +1 -0
  66. data/lib/mongo/monitoring/event/cmap/pool_created.rb +1 -0
  67. data/lib/mongo/monitoring/event/cmap/pool_ready.rb +1 -0
  68. data/lib/mongo/monitoring/event/command_failed.rb +1 -0
  69. data/lib/mongo/monitoring/event/command_started.rb +1 -0
  70. data/lib/mongo/monitoring/event/command_succeeded.rb +1 -0
  71. data/lib/mongo/monitoring/event/secure.rb +12 -17
  72. data/lib/mongo/monitoring/event/server_closed.rb +1 -0
  73. data/lib/mongo/monitoring/event/server_description_changed.rb +1 -0
  74. data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +1 -0
  75. data/lib/mongo/monitoring/event/server_heartbeat_started.rb +1 -0
  76. data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +1 -0
  77. data/lib/mongo/monitoring/event/server_opening.rb +1 -0
  78. data/lib/mongo/monitoring/event/topology_changed.rb +1 -0
  79. data/lib/mongo/monitoring/event/topology_closed.rb +1 -0
  80. data/lib/mongo/monitoring/event/topology_opening.rb +1 -0
  81. data/lib/mongo/operation/create/op_msg.rb +1 -0
  82. data/lib/mongo/operation/create_index/op_msg.rb +2 -1
  83. data/lib/mongo/operation/cursor_command/op_msg.rb +37 -0
  84. data/lib/mongo/operation/cursor_command/result.rb +60 -0
  85. data/lib/mongo/operation/cursor_command.rb +33 -0
  86. data/lib/mongo/operation/delete/op_msg.rb +1 -0
  87. data/lib/mongo/operation/drop/op_msg.rb +1 -0
  88. data/lib/mongo/operation/drop_database/op_msg.rb +1 -0
  89. data/lib/mongo/operation/drop_index/op_msg.rb +1 -0
  90. data/lib/mongo/operation/find/builder/command.rb +1 -1
  91. data/lib/mongo/operation/insert/bulk_result.rb +2 -4
  92. data/lib/mongo/operation/insert/op_msg.rb +1 -0
  93. data/lib/mongo/operation/result.rb +21 -25
  94. data/lib/mongo/operation/shared/causal_consistency_supported.rb +4 -2
  95. data/lib/mongo/operation/shared/executable.rb +2 -15
  96. data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
  97. data/lib/mongo/operation/shared/sessions_supported.rb +3 -5
  98. data/lib/mongo/operation/update/bulk_result.rb +1 -1
  99. data/lib/mongo/operation/update/op_msg.rb +1 -0
  100. data/lib/mongo/operation/write_command/op_msg.rb +2 -0
  101. data/lib/mongo/operation.rb +1 -0
  102. data/lib/mongo/options/redacted.rb +2 -2
  103. data/lib/mongo/protocol/compressed.rb +15 -11
  104. data/lib/mongo/protocol/message.rb +16 -20
  105. data/lib/mongo/protocol/msg.rb +1 -12
  106. data/lib/mongo/protocol/registry.rb +1 -1
  107. data/lib/mongo/protocol/serializers.rb +1 -3
  108. data/lib/mongo/query_cache.rb +3 -5
  109. data/lib/mongo/retryable/backpressure.rb +17 -2
  110. data/lib/mongo/retryable/read_worker.rb +1 -1
  111. data/lib/mongo/retryable/retry_policy.rb +2 -2
  112. data/lib/mongo/retryable/write_worker.rb +2 -2
  113. data/lib/mongo/retryable.rb +1 -1
  114. data/lib/mongo/server/app_metadata.rb +1 -1
  115. data/lib/mongo/server/connection.rb +3 -1
  116. data/lib/mongo/server/connection_common.rb +9 -1
  117. data/lib/mongo/server/connection_pool/generation_manager.rb +1 -1
  118. data/lib/mongo/server/connection_pool.rb +24 -10
  119. data/lib/mongo/server/description/features.rb +1 -2
  120. data/lib/mongo/server/description.rb +1 -2
  121. data/lib/mongo/server/monitor/connection.rb +3 -2
  122. data/lib/mongo/server/monitor.rb +133 -30
  123. data/lib/mongo/server/pending_connection.rb +1 -5
  124. data/lib/mongo/server/push_monitor.rb +16 -2
  125. data/lib/mongo/server.rb +28 -9
  126. data/lib/mongo/server_selector/base.rb +3 -6
  127. data/lib/mongo/server_selector/secondary_preferred.rb +4 -1
  128. data/lib/mongo/session.rb +25 -26
  129. data/lib/mongo/socket/ssl.rb +3 -3
  130. data/lib/mongo/socket.rb +1 -7
  131. data/lib/mongo/srv/monitor.rb +11 -2
  132. data/lib/mongo/srv/resolver.rb +1 -1
  133. data/lib/mongo/srv/result.rb +5 -3
  134. data/lib/mongo/timeout.rb +10 -15
  135. data/lib/mongo/tracing/open_telemetry/command_tracer.rb +16 -2
  136. data/lib/mongo/uri/options_mapper.rb +36 -13
  137. data/lib/mongo/uri/srv_protocol.rb +4 -4
  138. data/lib/mongo/uri.rb +56 -8
  139. data/lib/mongo/utils.rb +1 -1
  140. data/lib/mongo/version.rb +1 -1
  141. metadata +6 -4
  142. data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +0 -173
  143. data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +0 -1164
@@ -18,24 +18,6 @@ module Mongo
18
18
  class Error
19
19
  # Raised if an unsupported option is specified for an operation.
20
20
  class UnsupportedOption < Error
21
- # The error message provided when the user passes the hint option to
22
- # a write operation against a server that does not support the hint
23
- # option and does not provide option validation.
24
- #
25
- # @api private
26
- HINT_MESSAGE = 'The MongoDB server handling this request does not support ' \
27
- 'the hint option on this command. The hint option is supported on update ' \
28
- 'commands on MongoDB server versions 4.2 and later and on findAndModify ' \
29
- 'and delete commands on MongoDB server versions 4.4 and later'
30
-
31
- # The error message provided when the user passes the hint option to
32
- # an unacknowledged write operation.
33
- #
34
- # @api private
35
- UNACKNOWLEDGED_HINT_MESSAGE = 'The hint option cannot be specified on ' \
36
- 'an unacknowledged write operation. Remove the hint option or perform ' \
37
- 'this operation with a write concern of at least { w: 1 }'
38
-
39
21
  # The error message provided when the user passes the allow_disk_use
40
22
  # option to a find operation against a server that does not support the
41
23
  # allow_disk_use operation and does not provide option validation.
@@ -56,28 +38,6 @@ module Mongo
56
38
  'option is supported on createIndexes commands on MongoDB server versions ' \
57
39
  '4.4 and later'
58
40
 
59
- # Raise an error about an unsupported hint option.
60
- #
61
- # @option options [ Boolean ] unacknowledged_write Whether this error
62
- # pertains to a hint option passed to an unacknowledged write. Defaults
63
- # to false.
64
- #
65
- # @return [ Mongo::Error::UnsupportedOption ] An error with a default
66
- # error message.
67
- #
68
- # @api private
69
- def self.hint_error(**options)
70
- unacknowledged_write = options[:unacknowledged_write] || false
71
-
72
- error_message = if unacknowledged_write
73
- UNACKNOWLEDGED_HINT_MESSAGE
74
- else
75
- HINT_MESSAGE
76
- end
77
-
78
- new(error_message)
79
- end
80
-
81
41
  # Raise an error about an unsupported allow_disk_use option.
82
42
  #
83
43
  # @return [ Mongo::Error::UnsupportedOption ] An error with a default
@@ -218,10 +218,10 @@ module Mongo
218
218
  def delete(id, opts = {})
219
219
  timeout_holder = CsotTimeoutHolder.new(operation_timeouts: operation_timeouts(opts))
220
220
  result = files_collection
221
- .find({ _id: id }, @options.merge(timeout_ms: timeout_holder.remaining_timeout_ms))
221
+ .find({ _id: { '$eq' => id } }, @options.merge(timeout_ms: timeout_holder.remaining_timeout_ms))
222
222
  .delete_one(timeout_ms: timeout_holder.remaining_timeout_ms)
223
223
  chunks_collection
224
- .find({ files_id: id }, @options.merge(timeout_ms: timeout_holder.remaining_timeout_ms))
224
+ .find({ files_id: { '$eq' => id } }, @options.merge(timeout_ms: timeout_holder.remaining_timeout_ms))
225
225
  .delete_many(timeout_ms: timeout_holder.remaining_timeout_ms)
226
226
  raise Error::FileNotFound.new(id, :id) if result.n == 0
227
227
 
@@ -480,7 +480,7 @@ module Mongo
480
480
  #
481
481
  # @since 2.1.0
482
482
  def write_concern
483
- @write_concern ||= if wco = @options[:write_concern] || @options[:write]
483
+ @write_concern ||= if (wco = @options[:write_concern] || @options[:write])
484
484
  WriteConcern.get(wco)
485
485
  else
486
486
  database.write_concern
@@ -494,6 +494,32 @@ module Mongo
494
494
  chunks_collection.drop(timeout_ms: context.remaining_timeout_ms)
495
495
  end
496
496
 
497
+ # Ensures the files and chunks collections have their required indexes,
498
+ # creating any that are missing.
499
+ #
500
+ # @param [ CsotTimeoutHolder | nil ] timeout_holder The timeout holder.
501
+ #
502
+ # @api private
503
+ def ensure_indexes!(timeout_holder = nil)
504
+ fc_idx = files_collection.find(
505
+ {},
506
+ limit: 1,
507
+ projection: { _id: 1 },
508
+ timeout_ms: timeout_holder&.remaining_timeout_ms
509
+ ).first
510
+ create_index_if_missing!(files_collection, FSBucket::FILES_INDEX) if fc_idx.nil?
511
+
512
+ cc_idx = chunks_collection.find(
513
+ {},
514
+ limit: 1,
515
+ projection: { _id: 1 },
516
+ timeout_ms: timeout_holder&.remaining_timeout_ms
517
+ ).first
518
+ return unless cc_idx.nil?
519
+
520
+ create_index_if_missing!(chunks_collection, FSBucket::CHUNKS_INDEX, unique: true)
521
+ end
522
+
497
523
  private
498
524
 
499
525
  # @param [ Hash ] opts The options.
@@ -516,26 +542,6 @@ module Mongo
516
542
  "#{prefix}.#{Grid::File::Info::COLLECTION}"
517
543
  end
518
544
 
519
- def ensure_indexes!(timeout_holder = nil)
520
- fc_idx = files_collection.find(
521
- {},
522
- limit: 1,
523
- projection: { _id: 1 },
524
- timeout_ms: timeout_holder&.remaining_timeout_ms
525
- ).first
526
- create_index_if_missing!(files_collection, FSBucket::FILES_INDEX) if fc_idx.nil?
527
-
528
- cc_idx = chunks_collection.find(
529
- {},
530
- limit: 1,
531
- projection: { _id: 1 },
532
- timeout_ms: timeout_holder&.remaining_timeout_ms
533
- ).first
534
- return unless cc_idx.nil?
535
-
536
- create_index_if_missing!(chunks_collection, FSBucket::CHUNKS_INDEX, unique: true)
537
- end
538
-
539
545
  def create_index_if_missing!(collection, index_spec, options = {})
540
546
  indexes_view = collection.indexes
541
547
  begin
@@ -182,7 +182,7 @@ module Mongo
182
182
  @file_info ||= begin
183
183
  doc = options[:file_info_doc] ||
184
184
  fs.files_collection.find(
185
- { _id: file_id },
185
+ { _id: { '$eq' => file_id } },
186
186
  { timeout_ms: @timeout_holder.remaining_timeout_ms! }
187
187
  ).first
188
188
  File::Info.new(Options::Mapper.transform(doc, File::Info::MAPPINGS.invert)) if doc
@@ -216,7 +216,7 @@ module Mongo
216
216
  opts[:timeout_mode] = :cursor_lifetime
217
217
  end
218
218
 
219
- fs.chunks_collection.find({ files_id: file_id }, opts).sort(n: 1)
219
+ fs.chunks_collection.find({ files_id: { '$eq' => file_id } }, opts).sort(n: 1)
220
220
  end
221
221
  end
222
222
 
@@ -148,7 +148,7 @@ module Mongo
148
148
  #
149
149
  # @since 2.1.0
150
150
  def write_concern
151
- @write_concern ||= if wco = @options[:write_concern] || @options[:write]
151
+ @write_concern ||= if (wco = @options[:write_concern] || @options[:write])
152
152
  WriteConcern.get(wco)
153
153
  else
154
154
  fs.write_concern
@@ -177,7 +177,7 @@ module Mongo
177
177
  # @since 2.1.0
178
178
  def abort
179
179
  fs.chunks_collection.find(
180
- { files_id: file_id },
180
+ { files_id: { '$eq' => file_id } },
181
181
  @options.merge(timeout_ms: @timeout_holder.remaining_timeout_ms!)
182
182
  ).delete_many
183
183
  (@open = false) || true
@@ -212,7 +212,7 @@ module Mongo
212
212
  end
213
213
 
214
214
  def ensure_indexes!
215
- fs.send(:ensure_indexes!, @timeout_holder)
215
+ fs.ensure_indexes!(@timeout_holder)
216
216
  end
217
217
 
218
218
  def ensure_open!
@@ -168,11 +168,11 @@ module Mongo
168
168
  options = options.dup
169
169
 
170
170
  create_options = {}
171
- if session = @options[:session]
171
+ if (session = @options[:session])
172
172
  create_options[:session] = session
173
173
  end
174
174
  %i[commit_quorum session comment timeout_ms max_time_ms].each do |key|
175
- if value = options.delete(key)
175
+ if (value = options.delete(key))
176
176
  create_options[key] = value
177
177
  end
178
178
  end
@@ -347,10 +347,20 @@ module Mongo
347
347
  end
348
348
  end
349
349
 
350
+ # The query limit for an index view. Always -1; present so a Cursor
351
+ # can treat an index view like a collection view.
352
+ #
353
+ # @api private
354
+ def limit
355
+ -1
356
+ end
357
+
350
358
  private
351
359
 
352
360
  def drop_by_name(name, opts = {})
353
- client.send(:with_session, @options) do |session|
361
+ session_options = @options.dup
362
+ session_options[:session] = opts[:session] if opts[:session]
363
+ client.with_session(session_options) do |session|
354
364
  spec = {
355
365
  db_name: database.name,
356
366
  coll_name: collection.name,
@@ -394,10 +404,6 @@ module Mongo
394
404
  Operation::Indexes.new(indexes_spec(session))
395
405
  end
396
406
 
397
- def limit
398
- -1
399
- end
400
-
401
407
  def normalize_keys(spec)
402
408
  return false if spec.is_a?(String)
403
409
 
@@ -62,6 +62,7 @@ module Mongo
62
62
  # @since 2.9.0
63
63
  # @api private
64
64
  def initialize(address, reason)
65
+ super()
65
66
  @reason = reason
66
67
  @address = address
67
68
  end
@@ -35,6 +35,7 @@ module Mongo
35
35
  # @since 2.9.0
36
36
  # @api private
37
37
  def initialize(address)
38
+ super()
38
39
  @address = address
39
40
  end
40
41
 
@@ -47,6 +47,7 @@ module Mongo
47
47
  # @since 2.9.0
48
48
  # @api private
49
49
  def initialize(address, id, pool)
50
+ super()
50
51
  @address = address
51
52
  @connection_id = id
52
53
  @pool = pool
@@ -48,6 +48,7 @@ module Mongo
48
48
  # @since 2.9.0
49
49
  # @api private
50
50
  def initialize(address, id, pool)
51
+ super()
51
52
  @address = address
52
53
  @connection_id = id
53
54
  @pool = pool
@@ -79,6 +79,7 @@ module Mongo
79
79
  # @since 2.9.0
80
80
  # @api private
81
81
  def initialize(address, id, reason)
82
+ super()
82
83
  @reason = reason
83
84
  @address = address
84
85
  @connection_id = id
@@ -41,6 +41,7 @@ module Mongo
41
41
  # @since 2.9.0
42
42
  # @api private
43
43
  def initialize(address, id)
44
+ super()
44
45
  @address = address
45
46
  @connection_id = id
46
47
  end
@@ -41,6 +41,7 @@ module Mongo
41
41
  # @since 2.9.0
42
42
  # @api private
43
43
  def initialize(address, id)
44
+ super()
44
45
  @address = address
45
46
  @connection_id = id
46
47
  end
@@ -43,6 +43,7 @@ module Mongo
43
43
  #
44
44
  # @api private
45
45
  def initialize(address, service_id: nil, interrupt_in_use_connections: nil)
46
+ super()
46
47
  @address = address
47
48
  @service_id = service_id
48
49
  @options = {}
@@ -42,6 +42,7 @@ module Mongo
42
42
  # @since 2.9.0
43
43
  # @api private
44
44
  def initialize(address, pool)
45
+ super()
45
46
  @address = address
46
47
  @pool = pool
47
48
  end
@@ -48,6 +48,7 @@ module Mongo
48
48
  # @since 2.9.0
49
49
  # @api private
50
50
  def initialize(address, options, pool)
51
+ super()
51
52
  @address = address
52
53
  @options = options.dup.freeze
53
54
  @pool = pool
@@ -41,6 +41,7 @@ module Mongo
41
41
  # @since 2.9.0
42
42
  # @api private
43
43
  def initialize(address, options, pool)
44
+ super()
44
45
  @address = address
45
46
  @options = options.dup.freeze
46
47
  @pool = pool
@@ -83,6 +83,7 @@ module Mongo
83
83
  def initialize(command_name, database_name, address,
84
84
  request_id, operation_id, message, failure, duration,
85
85
  started_event:, server_connection_id: nil, service_id: nil)
86
+ super()
86
87
  @command_name = command_name.to_s
87
88
  @database_name = database_name
88
89
  @address = address
@@ -84,6 +84,7 @@ module Mongo
84
84
  operation_id, command, socket_object_id: nil, connection_id: nil,
85
85
  connection_generation: nil, server_connection_id: nil,
86
86
  service_id: nil)
87
+ super()
87
88
  @command_name = command_name.to_s
88
89
  @database_name = database_name
89
90
  @address = address
@@ -76,6 +76,7 @@ module Mongo
76
76
  def initialize(command_name, database_name, address, request_id,
77
77
  operation_id, reply, duration, started_event:,
78
78
  server_connection_id: nil, service_id: nil)
79
+ super()
79
80
  @command_name = command_name.to_s
80
81
  @database_name = database_name
81
82
  @address = address
@@ -47,18 +47,14 @@ module Mongo
47
47
  #
48
48
  # @return [ true | false ] Whether the command is sensitive.
49
49
  def sensitive?(command_name:, document:)
50
- if REDACTED_COMMANDS.include?(command_name.to_s)
51
- true
52
- elsif %w[hello ismaster isMaster].include?(command_name.to_s) &&
53
- document['speculativeAuthenticate']
54
- # According to Command Monitoring spec, for hello/legacy hello commands
55
- # when speculativeAuthenticate is present, their commands AND replies
56
- # MUST be redacted from the events.
57
- # See https://github.com/mongodb/specifications/blob/master/source/command-logging-and-monitoring/command-logging-and-monitoring.md#security
58
- true
59
- else
60
- false
61
- end
50
+ return true if REDACTED_COMMANDS.include?(command_name.to_s)
51
+
52
+ # According to Command Monitoring spec, for hello/legacy hello commands
53
+ # when speculativeAuthenticate is present, their commands AND replies
54
+ # MUST be redacted from the events.
55
+ # See https://github.com/mongodb/specifications/blob/master/source/command-logging-and-monitoring/command-logging-and-monitoring.md#security
56
+ %w[hello ismaster isMaster].include?(command_name.to_s) &&
57
+ !!document['speculativeAuthenticate']
62
58
  end
63
59
 
64
60
  # Redact secure information from the document if:
@@ -77,11 +73,10 @@ module Mongo
77
73
  #
78
74
  # @since 2.1.0
79
75
  def redacted(command_name, document)
80
- if %w[1 true yes].include?(ENV['MONGO_RUBY_DRIVER_UNREDACT_EVENTS']&.downcase)
81
- document
82
- elsif respond_to?(:started_event) && started_event.sensitive
83
- BSON::Document.new
84
- elsif sensitive?(command_name: command_name, document: document)
76
+ return document if %w[1 true yes].include?(ENV['MONGO_RUBY_DRIVER_UNREDACT_EVENTS']&.downcase)
77
+
78
+ if (respond_to?(:started_event) && started_event.sensitive) ||
79
+ sensitive?(command_name: command_name, document: document)
85
80
  BSON::Document.new
86
81
  else
87
82
  document
@@ -37,6 +37,7 @@ module Mongo
37
37
  #
38
38
  # @since 2.4.0
39
39
  def initialize(address, topology)
40
+ super()
40
41
  @address = address
41
42
  @topology = topology
42
43
  end
@@ -58,6 +58,7 @@ module Mongo
58
58
  # @api private
59
59
  def initialize(address, topology, previous_description, new_description,
60
60
  awaited: false)
61
+ super()
61
62
  @address = address
62
63
  @topology = topology
63
64
  @previous_description = previous_description
@@ -35,6 +35,7 @@ module Mongo
35
35
  # @since 2.7.0
36
36
  # @api private
37
37
  def initialize(address, round_trip_time, error, started_event:, awaited: false)
38
+ super()
38
39
  @address = address
39
40
  @round_trip_time = round_trip_time
40
41
  @error = error
@@ -40,6 +40,7 @@ module Mongo
40
40
  # @since 2.7.0
41
41
  # @api private
42
42
  def initialize(address, awaited: false)
43
+ super()
43
44
  @address = address
44
45
  @awaited = !!awaited
45
46
  end
@@ -35,6 +35,7 @@ module Mongo
35
35
  # @since 2.7.0
36
36
  # @api private
37
37
  def initialize(address, round_trip_time, started_event:, awaited: false)
38
+ super()
38
39
  @address = address
39
40
  @round_trip_time = round_trip_time
40
41
  @awaited = !!awaited
@@ -37,6 +37,7 @@ module Mongo
37
37
  #
38
38
  # @since 2.4.0
39
39
  def initialize(address, topology)
40
+ super()
40
41
  @address = address
41
42
  @topology = topology
42
43
  end
@@ -37,6 +37,7 @@ module Mongo
37
37
  #
38
38
  # @since 2.4.0
39
39
  def initialize(previous_topology, new_topology)
40
+ super()
40
41
  @previous_topology = previous_topology
41
42
  @new_topology = new_topology
42
43
  end
@@ -33,6 +33,7 @@ module Mongo
33
33
  #
34
34
  # @since 2.4.0
35
35
  def initialize(topology)
36
+ super()
36
37
  @topology = topology
37
38
  end
38
39
 
@@ -33,6 +33,7 @@ module Mongo
33
33
  #
34
34
  # @since 2.4.0
35
35
  def initialize(topology)
36
+ super()
36
37
  @topology = topology
37
38
  end
38
39
 
@@ -24,6 +24,7 @@ module Mongo
24
24
  # @since 2.5.2
25
25
  class OpMsg < OpMsgBase
26
26
  include ExecutableTransactionLabel
27
+ include CausalConsistencySupported
27
28
 
28
29
  private
29
30
 
@@ -24,6 +24,7 @@ module Mongo
24
24
  # @since 2.5.2
25
25
  class OpMsg < OpMsgBase
26
26
  include ExecutableTransactionLabel
27
+ include CausalConsistencySupported
27
28
 
28
29
  private
29
30
 
@@ -33,7 +34,7 @@ module Mongo
33
34
  indexes: indexes,
34
35
  comment: spec[:comment],
35
36
  }.compact.tap do |selector|
36
- if commit_quorum = spec[:commit_quorum]
37
+ if (commit_quorum = spec[:commit_quorum])
37
38
  # There was a bug on server versions 4.2.0 - 4.2.5 where
38
39
  # the server would accept the commitQuorum option and use it internally
39
40
  # (see SERVER-47193). As a result, the drivers specifications require
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025 MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Mongo
18
+ module Operation
19
+ class CursorCommand
20
+ # A cursor command operation sent as an op message.
21
+ #
22
+ # @api private
23
+ class OpMsg < OpMsgBase
24
+ include PolymorphicResult
25
+
26
+ private
27
+
28
+ # The user's command is sent verbatim. The driver MUST NOT inspect or
29
+ # modify it; $db, lsid and other internal fields are attached by the
30
+ # shared command building code.
31
+ def selector(_connection)
32
+ spec[:selector].dup
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025 MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Mongo
18
+ module Operation
19
+ class CursorCommand
20
+ # Parses the cursor field of a command response so a Cursor can be built
21
+ # from the result. The parsing is identical to a find command result.
22
+ #
23
+ # @api private
24
+ class Result < Operation::Result
25
+ # @return [ true | false ] Whether the command response contained a
26
+ # cursor field.
27
+ def cursor?
28
+ !cursor_document.nil?
29
+ end
30
+
31
+ # @return [ Integer | nil ] The cursor id from the cursor document.
32
+ def cursor_id
33
+ cursor? ? cursor_document[CURSOR_ID] : super
34
+ end
35
+
36
+ # @return [ Array<BSON::Document> ] The first batch of documents.
37
+ def documents
38
+ cursor? ? cursor_document[FIRST_BATCH] : []
39
+ end
40
+
41
+ # @return [ String | nil ] The cursor namespace, "database.collection".
42
+ def namespace
43
+ cursor? ? cursor_document['ns'] : super
44
+ end
45
+
46
+ private
47
+
48
+ def cursor_document
49
+ return @cursor_document if defined?(@cursor_document)
50
+
51
+ @cursor_document = first_document[CURSOR]
52
+ end
53
+
54
+ def first_document
55
+ @first_document ||= reply.documents[0]
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Copyright (C) 2025 MongoDB Inc.
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ require 'mongo/operation/cursor_command/op_msg'
18
+ require 'mongo/operation/cursor_command/result'
19
+
20
+ module Mongo
21
+ module Operation
22
+ # A command operation whose response is parsed as a cursor.
23
+ #
24
+ # Unlike Command, the result exposes the firstBatch, namespace, and cursor
25
+ # id from the command response so that a Cursor can be built from it.
26
+ #
27
+ # @api private
28
+ class CursorCommand
29
+ include Specifiable
30
+ include OpMsgExecutable
31
+ end
32
+ end
33
+ end
@@ -27,6 +27,7 @@ module Mongo
27
27
  include ExecutableNoValidate
28
28
  include ExecutableTransactionLabel
29
29
  include PolymorphicResult
30
+ include CausalConsistencySupported
30
31
 
31
32
  private
32
33
 
@@ -24,6 +24,7 @@ module Mongo
24
24
  # @since 2.5.2
25
25
  class OpMsg < OpMsgBase
26
26
  include ExecutableTransactionLabel
27
+ include CausalConsistencySupported
27
28
  end
28
29
  end
29
30
  end