mongo 2.22.0 → 2.23.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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/lib/mongo/client.rb +40 -4
  3. data/lib/mongo/cluster.rb +4 -1
  4. data/lib/mongo/collection/view/aggregation/behavior.rb +1 -1
  5. data/lib/mongo/collection/view/aggregation.rb +5 -2
  6. data/lib/mongo/collection/view/iterable.rb +16 -14
  7. data/lib/mongo/collection/view/readable.rb +64 -55
  8. data/lib/mongo/collection/view/writable.rb +52 -46
  9. data/lib/mongo/collection/view.rb +2 -0
  10. data/lib/mongo/collection.rb +56 -46
  11. data/lib/mongo/config.rb +4 -0
  12. data/lib/mongo/crypt/auto_decryption_context.rb +9 -0
  13. data/lib/mongo/crypt/binding.rb +1 -1
  14. data/lib/mongo/crypt/context.rb +10 -0
  15. data/lib/mongo/crypt/explicit_decryption_context.rb +9 -0
  16. data/lib/mongo/database/view.rb +25 -20
  17. data/lib/mongo/database.rb +17 -10
  18. data/lib/mongo/deprecations.rb +98 -0
  19. data/lib/mongo/index/view.rb +28 -19
  20. data/lib/mongo/operation/create.rb +4 -0
  21. data/lib/mongo/operation/insert/op_msg.rb +5 -2
  22. data/lib/mongo/operation/shared/executable.rb +11 -4
  23. data/lib/mongo/operation/shared/specifiable.rb +5 -1
  24. data/lib/mongo/search_index/view.rb +29 -9
  25. data/lib/mongo/server/app_metadata/platform.rb +17 -4
  26. data/lib/mongo/server/connection.rb +18 -0
  27. data/lib/mongo/server/description/features.rb +37 -8
  28. data/lib/mongo/server.rb +2 -1
  29. data/lib/mongo/session.rb +55 -19
  30. data/lib/mongo/srv/monitor.rb +5 -1
  31. data/lib/mongo/srv/result.rb +14 -4
  32. data/lib/mongo/tracing/open_telemetry/command_tracer.rb +320 -0
  33. data/lib/mongo/tracing/open_telemetry/operation_tracer.rb +227 -0
  34. data/lib/mongo/tracing/open_telemetry/tracer.rb +236 -0
  35. data/lib/mongo/tracing/open_telemetry.rb +27 -0
  36. data/lib/mongo/tracing.rb +42 -0
  37. data/lib/mongo/uri/srv_protocol.rb +11 -6
  38. data/lib/mongo/version.rb +1 -1
  39. data/lib/mongo.rb +3 -0
  40. metadata +8 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bfc6de88aae51217bcbe02307215fefb67259f3257c5eba94c966fa8ceac5ccd
4
- data.tar.gz: 258a3151671bf5ef8f6ece898dee5846b767ea5ed537fc2a86699ca688285176
3
+ metadata.gz: e69a3d0fe1586e73885c27a97616bb2422847a13a6b86e1c7f95348261d7de58
4
+ data.tar.gz: ff6fc65770491d22c49221140e248d37edbb58c3715808843718cb2b9fc8e331
5
5
  SHA512:
6
- metadata.gz: 2c32a72398d175523f643ad4e229f406e82f450d5eb254ee3e05815645750dd578bca77da03ee5c546146c5d78779cced7c97485107589f057fef3fcb1097662
7
- data.tar.gz: 1b3dfcefc33c710792591177f18ea274439326cac1c525cc13d39c6551ac33582baa579082832422166fd819cfa68815659925d925e34f8a4e1026f244fe63f2
6
+ metadata.gz: fc176435fcf633b0b3acd905bcbca387054f70210c3d140223b30eadbed7667e56ee3ae868ad003d47b89992de09da19fc0bcfc1009f186b8e4bbda1caead6a3
7
+ data.tar.gz: c5ca31db40bde02be00178be089fe7c7f47504374fd606b84696ddf3ae94d14bc7f2efb00a6c7093a224451022a0098e7528268b364a731e9d95db72f3f23ddf
data/lib/mongo/client.rb CHANGED
@@ -112,6 +112,7 @@ module Mongo
112
112
  :ssl_verify_hostname,
113
113
  :ssl_verify_ocsp_endpoint,
114
114
  :timeout_ms,
115
+ :tracing,
115
116
  :truncate_logs,
116
117
  :user,
117
118
  :wait_queue_timeout,
@@ -356,7 +357,9 @@ module Mongo
356
357
  # that the driver will communicate with for sharded topologies. If this
357
358
  # option is 0, then there will be no maximum number of mongoses. If the
358
359
  # given URI resolves to more hosts than ``:srv_max_hosts``, the client
359
- # will ramdomly choose an ``:srv_max_hosts`` sized subset of hosts.
360
+ # will randomly choose an ``:srv_max_hosts`` sized subset of hosts. If
361
+ # srvMaxHosts is provided in the URI options, it takes precedence over this
362
+ # option.
360
363
  # @option options [ String ] :srv_service_name The service name to use in
361
364
  # the SRV DNS query.
362
365
  # @option options [ true, false ] :ssl Whether to use TLS.
@@ -437,6 +440,20 @@ module Mongo
437
440
  # See Ruby's Zlib module for valid levels.
438
441
  # @option options [ Hash ] :resolv_options For internal driver use only.
439
442
  # Options to pass through to Resolv::DNS constructor for SRV lookups.
443
+ # @option options [ Hash ] :tracing OpenTelemetry tracing options.
444
+ # - :enabled => Boolean, whether to enable OpenTelemetry tracing. The default
445
+ # value is nil that means that the configuration will be taken from the
446
+ # OTEL_RUBY_INSTRUMENTATION_MONGODB_ENABLED environment variable.
447
+ # - :tracer => OpenTelemetry::Trace::Tracer, the tracer to use for
448
+ # tracing. Must be an implementation of OpenTelemetry::Trace::Tracer
449
+ # interface.
450
+ # - :query_text_max_length => Integer, the maximum length of the query text
451
+ # to be included in the span attributes. If the query text exceeds this
452
+ # length, it will be truncated. Value 0 means no query text
453
+ # will be included in the span attributes. The default value is nil that
454
+ # means that the configuration will be taken from the
455
+ # OTEL_RUBY_INSTRUMENTATION_MONGODB_QUERY_TEXT_MAX_LENGTH environment
456
+ # variable.
440
457
  # @option options [ Hash ] :auto_encryption_options Auto-encryption related
441
458
  # options.
442
459
  # - :key_vault_client => Client | nil, a client connected to the MongoDB
@@ -574,8 +591,11 @@ module Mongo
574
591
 
575
592
  @connect_lock = Mutex.new
576
593
  @connect_lock.synchronize do
577
- @cluster = Cluster.new(addresses, @monitoring,
578
- cluster_options.merge(srv_uri: srv_uri))
594
+ @cluster = Cluster.new(
595
+ addresses,
596
+ @monitoring,
597
+ cluster_options.merge(srv_uri: srv_uri)
598
+ )
579
599
  end
580
600
 
581
601
  begin
@@ -623,6 +643,7 @@ module Mongo
623
643
  # applications should read these values from client, not from cluster
624
644
  max_read_retries: options[:max_read_retries],
625
645
  read_retry_interval: options[:read_retry_interval],
646
+ tracer: tracer,
626
647
  ).tap do |options|
627
648
  # If the client has a cluster already, forward srv_uri to the new
628
649
  # cluster to maintain SRV monitoring. If the client is brand new,
@@ -965,7 +986,10 @@ module Mongo
965
986
  cmd[:nameOnly] = !!name_only
966
987
  cmd[:filter] = filter unless filter.empty?
967
988
  cmd[:authorizedDatabases] = true if opts[:authorized_databases]
968
- use(Database::ADMIN).database.read_command(cmd, opts).first[Database::DATABASES]
989
+ use(Database::ADMIN)
990
+ .database
991
+ .read_command(cmd, opts.merge(op_name: 'listDatabases'))
992
+ .first[Database::DATABASES]
969
993
  end
970
994
 
971
995
  # Returns a list of Mongo::Database objects.
@@ -1195,6 +1219,18 @@ module Mongo
1195
1219
  end
1196
1220
  end
1197
1221
 
1222
+ # Get the tracer configured for this client.
1223
+ #
1224
+ # @return [ Tracing::Tracer | nil ] The tracer configured for this client.
1225
+ def tracer
1226
+ tracing_opts = @options[:tracing] || {}
1227
+ @tracer ||= Tracing.create_tracer(
1228
+ enabled: tracing_opts[:enabled],
1229
+ query_text_max_length: tracing_opts[:query_text_max_length],
1230
+ otel_tracer: tracing_opts[:tracer],
1231
+ )
1232
+ end
1233
+
1198
1234
  private
1199
1235
 
1200
1236
  # Attempts to parse the given list of addresses, using the provided options.
data/lib/mongo/cluster.rb CHANGED
@@ -126,6 +126,7 @@ module Mongo
126
126
  if options[:monitoring_io] == false && !options.key?(:cleanup)
127
127
  options[:cleanup] = false
128
128
  end
129
+ @tracer = options.delete(:tracer)
129
130
  @options = options.freeze
130
131
 
131
132
  # @update_lock covers @servers, @connecting, @connected, @topology and
@@ -298,7 +299,7 @@ module Mongo
298
299
  cluster = Cluster.new(
299
300
  client.cluster.addresses.map(&:to_s),
300
301
  monitoring || Monitoring.new,
301
- client.cluster_options,
302
+ client.cluster_options
302
303
  )
303
304
  client.instance_variable_set(:@cluster, cluster)
304
305
  end
@@ -309,6 +310,8 @@ module Mongo
309
310
  # @return [ Monitoring ] monitoring The monitoring.
310
311
  attr_reader :monitoring
311
312
 
313
+ attr_reader :tracer
314
+
312
315
  # @return [ Object ] The cluster topology.
313
316
  attr_reader :topology
314
317
 
@@ -88,7 +88,7 @@ module Mongo
88
88
  @view.send(:server_selector)
89
89
  end
90
90
 
91
- def aggregate_spec(session, read_preference)
91
+ def aggregate_spec(session, read_preference = nil)
92
92
  Builder::Aggregation.new(
93
93
  pipeline,
94
94
  view,
@@ -25,11 +25,14 @@ module Mongo
25
25
  #
26
26
  # @since 2.0.0
27
27
  class Aggregation
28
+ extend Forwardable
28
29
  include Behavior
29
30
 
30
31
  # @return [ Array<Hash> ] pipeline The aggregation pipeline.
31
32
  attr_reader :pipeline
32
33
 
34
+ def_delegators :view, :tracer
35
+
33
36
  # Initialize the aggregation for the provided collection view, pipeline
34
37
  # and options.
35
38
  #
@@ -80,7 +83,7 @@ module Mongo
80
83
  Aggregation.new(view, pipeline, options)
81
84
  end
82
85
 
83
- def initial_query_op(session, read_preference)
86
+ def initial_query_op(session, read_preference = nil)
84
87
  Operation::Aggregate.new(aggregate_spec(session, read_preference))
85
88
  end
86
89
 
@@ -117,7 +120,7 @@ module Mongo
117
120
 
118
121
  end
119
122
 
120
- def send_initial_query(server, context)
123
+ def send_initial_query(server, context, operation: nil)
121
124
  if server.load_balancer?
122
125
  # Connection will be checked in when cursor is drained.
123
126
  connection = server.pool.check_out(context: context)
@@ -88,19 +88,21 @@ module Mongo
88
88
  operation_timeouts: operation_timeouts,
89
89
  view: self
90
90
  )
91
-
92
- if respond_to?(:write?, true) && write?
93
- server = server_selector.select_server(cluster, nil, session, write_aggregation: true)
94
- result = send_initial_query(server, context)
95
-
96
- if use_query_cache?
97
- CachingCursor.new(view, result, server, session: session, context: context)
91
+ op = initial_query_op(session)
92
+ tracer.trace_operation(op, context) do
93
+ if respond_to?(:write?, true) && write?
94
+ server = server_selector.select_server(cluster, nil, session, write_aggregation: true)
95
+ result = send_initial_query(server, context, operation: op)
96
+
97
+ if use_query_cache?
98
+ CachingCursor.new(view, result, server, session: session, context: context)
99
+ else
100
+ Cursor.new(view, result, server, session: session, context: context)
101
+ end
98
102
  else
99
- Cursor.new(view, result, server, session: session, context: context)
100
- end
101
- else
102
- read_with_retry_cursor(session, server_selector, view, context: context) do |server|
103
- send_initial_query(server, context)
103
+ read_with_retry_cursor(session, server_selector, view, context: context) do |server|
104
+ send_initial_query(server, context, operation: op)
105
+ end
104
106
  end
105
107
  end
106
108
  end
@@ -167,8 +169,8 @@ module Mongo
167
169
  end
168
170
  end
169
171
 
170
- def send_initial_query(server, context)
171
- operation = initial_query_op(context.session)
172
+ def send_initial_query(server, context, operation: nil)
173
+ operation ||= initial_query_op(context.session)
172
174
  if server.load_balancer?
173
175
  # Connection will be checked in when cursor is drained.
174
176
  connection = server.pool.check_out(context: context)
@@ -192,22 +192,25 @@ module Mongo
192
192
  session: session,
193
193
  operation_timeouts: operation_timeouts(opts)
194
194
  )
195
- read_with_retry(session, selector, context) do |server|
196
- Operation::Count.new(
197
- selector: cmd,
198
- db_name: database.name,
199
- options: {:limit => -1},
200
- read: read_pref,
201
- session: session,
202
- # For some reason collation was historically accepted as a
203
- # string key. Note that this isn't documented as valid usage.
204
- collation: opts[:collation] || opts['collation'] || collation,
205
- comment: opts[:comment],
206
- ).execute(
207
- server,
208
- context: context
209
- )
210
- end.n.to_i
195
+ operation = Operation::Count.new(
196
+ selector: cmd,
197
+ db_name: database.name,
198
+ options: {:limit => -1},
199
+ read: read_pref,
200
+ session: session,
201
+ # For some reason collation was historically accepted as a
202
+ # string key. Note that this isn't documented as valid usage.
203
+ collation: opts[:collation] || opts['collation'] || collation,
204
+ comment: opts[:comment],
205
+ )
206
+ tracer.trace_operation(operation, context) do
207
+ read_with_retry(session, selector, context) do |server|
208
+ operation.execute(
209
+ server,
210
+ context: context
211
+ )
212
+ end.n.to_i
213
+ end
211
214
  end
212
215
  end
213
216
 
@@ -294,32 +297,35 @@ module Mongo
294
297
  session: session,
295
298
  operation_timeouts: operation_timeouts(opts)
296
299
  )
297
- read_with_retry(session, selector, context) do |server|
298
- cmd = { count: collection.name }
299
- cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
300
- if read_concern
301
- cmd[:readConcern] = Options::Mapper.transform_values_to_strings(read_concern)
300
+ cmd = { count: collection.name }
301
+ cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
302
+ if read_concern
303
+ cmd[:readConcern] = Options::Mapper.transform_values_to_strings(read_concern)
304
+ end
305
+ operation = Operation::Count.new(
306
+ selector: cmd,
307
+ db_name: database.name,
308
+ read: read_pref,
309
+ session: session,
310
+ comment: opts[:comment],
311
+ )
312
+ tracer.trace_operation(operation, context, op_name: 'estimatedDocumentCount') do
313
+ read_with_retry(session, selector, context) do |server|
314
+ result = operation.execute(server, context: context)
315
+ result.n.to_i
316
+ end
317
+ rescue Error::OperationFailure::Family => exc
318
+ if exc.code == 26
319
+ # NamespaceNotFound
320
+ # This should only happen with the aggregation pipeline path
321
+ # (server 4.9+). Previous servers should return 0 for nonexistent
322
+ # collections.
323
+ 0
324
+ else
325
+ raise
302
326
  end
303
- result = Operation::Count.new(
304
- selector: cmd,
305
- db_name: database.name,
306
- read: read_pref,
307
- session: session,
308
- comment: opts[:comment],
309
- ).execute(server, context: context)
310
- result.n.to_i
311
327
  end
312
328
  end
313
- rescue Error::OperationFailure::Family => exc
314
- if exc.code == 26
315
- # NamespaceNotFound
316
- # This should only happen with the aggregation pipeline path
317
- # (server 4.9+). Previous servers should return 0 for nonexistent
318
- # collections.
319
- 0
320
- else
321
- raise
322
- end
323
329
  end
324
330
 
325
331
  # Get a list of distinct values for a specific field.
@@ -362,22 +368,25 @@ module Mongo
362
368
  session: session,
363
369
  operation_timeouts: operation_timeouts(opts)
364
370
  )
365
- read_with_retry(session, selector, context) do |server|
366
- Operation::Distinct.new(
367
- selector: cmd,
368
- db_name: database.name,
369
- options: {:limit => -1},
370
- read: read_pref,
371
- session: session,
372
- comment: opts[:comment],
373
- # For some reason collation was historically accepted as a
374
- # string key. Note that this isn't documented as valid usage.
375
- collation: opts[:collation] || opts['collation'] || collation,
376
- ).execute(
377
- server,
378
- context: context
379
- )
380
- end.first['values']
371
+ operation = Operation::Distinct.new(
372
+ selector: cmd,
373
+ db_name: database.name,
374
+ options: {:limit => -1},
375
+ read: read_pref,
376
+ session: session,
377
+ comment: opts[:comment],
378
+ # For some reason collation was historically accepted as a
379
+ # string key. Note that this isn't documented as valid usage.
380
+ collation: opts[:collation] || opts['collation'] || collation,
381
+ )
382
+ tracer.trace_operation(operation, context) do
383
+ read_with_retry(session, selector, context) do |server|
384
+ operation.execute(
385
+ server,
386
+ context: context
387
+ )
388
+ end.first['values']
389
+ end
381
390
  end
382
391
  end
383
392
 
@@ -211,22 +211,24 @@ module Mongo
211
211
  session: session,
212
212
  operation_timeouts: operation_timeouts(opts)
213
213
  )
214
- write_with_retry(write_concern, context: context) do |connection, txn_num, context|
215
- gte_4_4 = connection.server.description.server_version_gte?('4.4')
216
- if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged?
217
- raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
214
+ operation = Operation::WriteCommand.new(
215
+ selector: cmd,
216
+ db_name: database.name,
217
+ write_concern: write_concern,
218
+ session: session,
219
+ )
220
+ value = tracer.trace_operation(operation, context, op_name: 'findOneAndUpdate') do
221
+ write_with_retry(write_concern, context: context) do |connection, txn_num, context|
222
+ gte_4_4 = connection.server.description.server_version_gte?('4.4')
223
+ if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged?
224
+ raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
225
+ end
226
+ operation.txn_num = txn_num
227
+ operation.execute_with_connection(connection, context: context)
218
228
  end
219
-
220
- Operation::WriteCommand.new(
221
- selector: cmd,
222
- db_name: database.name,
223
- write_concern: write_concern,
224
- session: session,
225
- txn_num: txn_num,
226
- ).execute_with_connection(connection, context: context)
227
- end
228
- end.first&.fetch('value', nil)
229
- value unless value.nil? || value.empty?
229
+ end.first&.fetch('value', nil)
230
+ value unless value.nil? || value.empty?
231
+ end
230
232
  end
231
233
 
232
234
  # Remove documents from the collection.
@@ -275,22 +277,24 @@ module Mongo
275
277
  session: session,
276
278
  operation_timeouts: operation_timeouts(opts)
277
279
  )
278
- nro_write_with_retry(write_concern, context: context) do |connection, txn_num, context|
279
- gte_4_4 = connection.server.description.server_version_gte?('4.4')
280
- if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged?
281
- raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
280
+ operation = Operation::Delete.new(
281
+ deletes: [ delete_doc ],
282
+ db_name: collection.database.name,
283
+ coll_name: collection.name,
284
+ write_concern: write_concern,
285
+ bypass_document_validation: !!opts[:bypass_document_validation],
286
+ session: session,
287
+ let: opts[:let],
288
+ comment: opts[:comment],
289
+ )
290
+ tracer.trace_operation(operation, context, op_name: 'deleteMany') do
291
+ nro_write_with_retry(write_concern, context: context) do |connection, txn_num, context|
292
+ gte_4_4 = connection.server.description.server_version_gte?('4.4')
293
+ if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged?
294
+ raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
295
+ end
296
+ operation.execute_with_connection(connection, context: context)
282
297
  end
283
-
284
- Operation::Delete.new(
285
- deletes: [ delete_doc ],
286
- db_name: collection.database.name,
287
- coll_name: collection.name,
288
- write_concern: write_concern,
289
- bypass_document_validation: !!opts[:bypass_document_validation],
290
- session: session,
291
- let: opts[:let],
292
- comment: opts[:comment],
293
- ).execute_with_connection(connection, context: context)
294
298
  end
295
299
  end
296
300
  end
@@ -592,23 +596,25 @@ module Mongo
592
596
  session: session,
593
597
  operation_timeouts: operation_timeouts(opts)
594
598
  )
595
- write_with_retry(write_concern, context: context) do |connection, txn_num, context|
596
- gte_4_2 = connection.server.description.server_version_gte?('4.2')
597
- if !gte_4_2 && opts[:hint] && write_concern && !write_concern.acknowledged?
598
- raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
599
+ operation = Operation::Update.new(
600
+ updates: [ update_doc ],
601
+ db_name: collection.database.name,
602
+ coll_name: collection.name,
603
+ write_concern: write_concern,
604
+ bypass_document_validation: !!opts[:bypass_document_validation],
605
+ session: session,
606
+ let: opts[:let],
607
+ comment: opts[:comment],
608
+ )
609
+ tracer.trace_operation(operation, context) do
610
+ write_with_retry(write_concern, context: context) do |connection, txn_num, context|
611
+ gte_4_2 = connection.server.description.server_version_gte?('4.2')
612
+ if !gte_4_2 && opts[:hint] && write_concern && !write_concern.acknowledged?
613
+ raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
614
+ end
615
+ operation.txn_num = txn_num
616
+ operation.execute_with_connection(connection, context: context)
599
617
  end
600
-
601
- Operation::Update.new(
602
- updates: [ update_doc ],
603
- db_name: collection.database.name,
604
- coll_name: collection.name,
605
- write_concern: write_concern,
606
- bypass_document_validation: !!opts[:bypass_document_validation],
607
- session: session,
608
- txn_num: txn_num,
609
- let: opts[:let],
610
- comment: opts[:comment],
611
- ).execute_with_connection(connection, context: context)
612
618
  end
613
619
  end
614
620
  end
@@ -72,6 +72,8 @@ module Mongo
72
72
  # Delegate to the cluster for the next primary.
73
73
  def_delegators :cluster, :next_primary
74
74
 
75
+ def_delegators :client, :tracer
76
+
75
77
  alias :selector :filter
76
78
 
77
79
  # @return [ Integer | nil | The timeout_ms value that was passed as an
@@ -57,6 +57,8 @@ module Mongo
57
57
  # Delegate to the cluster for the next primary.
58
58
  def_delegators :cluster, :next_primary
59
59
 
60
+ def_delegators :client, :tracer
61
+
60
62
  # Options that can be updated on a new Collection instance via the #with method.
61
63
  #
62
64
  # @since 2.1.0
@@ -410,21 +412,24 @@ module Mongo
410
412
  client: client,
411
413
  session: session
412
414
  )
413
- maybe_create_qe_collections(opts[:encrypted_fields], client, session) do |encrypted_fields|
414
- Operation::Create.new(
415
- selector: operation,
416
- db_name: database.name,
417
- write_concern: write_concern,
418
- session: session,
419
- # Note that these are collection options, collation isn't
420
- # taken from options passed to the create method.
421
- collation: options[:collation] || options['collation'],
422
- encrypted_fields: encrypted_fields,
423
- validator: options[:validator],
424
- ).execute(
425
- next_primary(nil, session),
426
- context: context
427
- )
415
+ operation = Operation::Create.new(
416
+ selector: operation,
417
+ db_name: database.name,
418
+ write_concern: write_concern,
419
+ session: session,
420
+ # Note that these are collection options, collation isn't
421
+ # taken from options passed to the create method.
422
+ collation: options[:collation] || options['collation'],
423
+ validator: options[:validator],
424
+ )
425
+ tracer.trace_operation(operation, context, op_name: 'createCollection') do
426
+ maybe_create_qe_collections(opts[:encrypted_fields], client, session) do |encrypted_fields|
427
+ operation.encrypted_fields = encrypted_fields
428
+ operation.execute(
429
+ next_primary(nil, session),
430
+ context: context
431
+ )
432
+ end
428
433
  end
429
434
  end
430
435
  end
@@ -453,25 +458,27 @@ module Mongo
453
458
  # @since 2.0.0
454
459
  def drop(opts = {})
455
460
  client.with_session(opts) do |session|
456
- maybe_drop_emm_collections(opts[:encrypted_fields], client, session) do
457
- temp_write_concern = write_concern
458
- write_concern = if opts[:write_concern]
459
- WriteConcern.get(opts[:write_concern])
460
- else
461
- temp_write_concern
461
+ context = Operation::Context.new(
462
+ client: client,
463
+ session: session,
464
+ operation_timeouts: operation_timeouts(opts)
465
+ )
466
+ temp_write_concern = write_concern
467
+ write_concern = if opts[:write_concern]
468
+ WriteConcern.get(opts[:write_concern])
469
+ else
470
+ temp_write_concern
471
+ end
472
+ operation = Operation::Drop.new({
473
+ selector: { :drop => name },
474
+ db_name: database.name,
475
+ write_concern: write_concern,
476
+ session: session,
477
+ })
478
+ tracer.trace_operation(operation, context, op_name: 'dropCollection') do
479
+ maybe_drop_emm_collections(opts[:encrypted_fields], client, session) do
480
+ do_drop(operation, session, context)
462
481
  end
463
- context = Operation::Context.new(
464
- client: client,
465
- session: session,
466
- operation_timeouts: operation_timeouts(opts)
467
- )
468
- operation = Operation::Drop.new({
469
- selector: { :drop => name },
470
- db_name: database.name,
471
- write_concern: write_concern,
472
- session: session,
473
- })
474
- do_drop(operation, session, context)
475
482
  end
476
483
  end
477
484
  end
@@ -865,19 +872,22 @@ module Mongo
865
872
  session: session,
866
873
  operation_timeouts: operation_timeouts(opts)
867
874
  )
868
- write_with_retry(write_concern, context: context) do |connection, txn_num, context|
869
- Operation::Insert.new(
870
- :documents => [ document ],
871
- :db_name => database.name,
872
- :coll_name => name,
873
- :write_concern => write_concern,
874
- :bypass_document_validation => !!opts[:bypass_document_validation],
875
- :options => opts,
876
- :id_generator => client.options[:id_generator],
877
- :session => session,
878
- :txn_num => txn_num,
879
- :comment => opts[:comment]
880
- ).execute_with_connection(connection, context: context)
875
+ operation = Operation::Insert.new(
876
+ :documents => [ document ],
877
+ :db_name => database.name,
878
+ :coll_name => name,
879
+ :write_concern => write_concern,
880
+ :bypass_document_validation => !!opts[:bypass_document_validation],
881
+ :options => opts,
882
+ :id_generator => client.options[:id_generator],
883
+ :session => session,
884
+ :comment => opts[:comment]
885
+ )
886
+ tracer.trace_operation(operation, context) do
887
+ write_with_retry(write_concern, context: context) do |connection, txn_num, context|
888
+ operation.txn_num = txn_num
889
+ operation.execute_with_connection(connection, context: context)
890
+ end
881
891
  end
882
892
  end
883
893
  end
data/lib/mongo/config.rb CHANGED
@@ -27,6 +27,10 @@ module Mongo
27
27
  # validate the parameters and raise an error if they are invalid.
28
28
  option :validate_update_replace, default: false
29
29
 
30
+ # When this flag is set to true, the CSFLE will use Ruby types for
31
+ # decryption instead of BSON types.
32
+ option :csfle_convert_to_ruby_types, default: false
33
+
30
34
  # Set the configuration options.
31
35
  #
32
36
  # @example Set the options.
@@ -38,6 +38,15 @@ module Mongo
38
38
 
39
39
  Binding.ctx_decrypt_init(self, @command)
40
40
  end
41
+
42
+ # Which BSON mode to use when creating documents from the outcome of
43
+ # the state machine. The returned value is based on the
44
+ # +Mongo::Config.csfle_convert_to_ruby_types+ option.
45
+ #
46
+ # @return [ Symbol, nil ] The BSON mode.
47
+ def bson_mode
48
+ Mongo::Config.csfle_convert_to_ruby_types ? nil : :bson
49
+ end
41
50
  end
42
51
  end
43
52
  end