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.
- checksums.yaml +4 -4
- data/lib/mongo/client.rb +40 -4
- data/lib/mongo/cluster.rb +4 -1
- data/lib/mongo/collection/view/aggregation/behavior.rb +1 -1
- data/lib/mongo/collection/view/aggregation.rb +5 -2
- data/lib/mongo/collection/view/iterable.rb +16 -14
- data/lib/mongo/collection/view/readable.rb +64 -55
- data/lib/mongo/collection/view/writable.rb +52 -46
- data/lib/mongo/collection/view.rb +2 -0
- data/lib/mongo/collection.rb +56 -46
- data/lib/mongo/config.rb +4 -0
- data/lib/mongo/crypt/auto_decryption_context.rb +9 -0
- data/lib/mongo/crypt/binding.rb +1 -1
- data/lib/mongo/crypt/context.rb +10 -0
- data/lib/mongo/crypt/explicit_decryption_context.rb +9 -0
- data/lib/mongo/database/view.rb +25 -20
- data/lib/mongo/database.rb +17 -10
- data/lib/mongo/deprecations.rb +98 -0
- data/lib/mongo/index/view.rb +28 -19
- data/lib/mongo/operation/create.rb +4 -0
- data/lib/mongo/operation/insert/op_msg.rb +5 -2
- data/lib/mongo/operation/shared/executable.rb +11 -4
- data/lib/mongo/operation/shared/specifiable.rb +5 -1
- data/lib/mongo/search_index/view.rb +29 -9
- data/lib/mongo/server/app_metadata/platform.rb +17 -4
- data/lib/mongo/server/connection.rb +18 -0
- data/lib/mongo/server/description/features.rb +37 -8
- data/lib/mongo/server.rb +2 -1
- data/lib/mongo/session.rb +55 -19
- data/lib/mongo/srv/monitor.rb +5 -1
- data/lib/mongo/srv/result.rb +14 -4
- data/lib/mongo/tracing/open_telemetry/command_tracer.rb +320 -0
- data/lib/mongo/tracing/open_telemetry/operation_tracer.rb +227 -0
- data/lib/mongo/tracing/open_telemetry/tracer.rb +236 -0
- data/lib/mongo/tracing/open_telemetry.rb +27 -0
- data/lib/mongo/tracing.rb +42 -0
- data/lib/mongo/uri/srv_protocol.rb +11 -6
- data/lib/mongo/version.rb +1 -1
- data/lib/mongo.rb +3 -0
- metadata +8 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e69a3d0fe1586e73885c27a97616bb2422847a13a6b86e1c7f95348261d7de58
|
|
4
|
+
data.tar.gz: ff6fc65770491d22c49221140e248d37edbb58c3715808843718cb2b9fc8e331
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
|
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(
|
|
578
|
-
|
|
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)
|
|
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
|
|
|
@@ -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
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
100
|
-
|
|
101
|
-
|
|
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
|
|
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
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
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
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
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
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
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
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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
|
-
|
|
221
|
-
|
|
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
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
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
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
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
|
data/lib/mongo/collection.rb
CHANGED
|
@@ -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
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
)
|
|
425
|
-
|
|
426
|
-
|
|
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
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
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
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
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
|