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.
- checksums.yaml +4 -4
- data/bin/mongo_console +2 -2
- data/lib/mongo/address/validator.rb +1 -1
- data/lib/mongo/address.rb +1 -3
- data/lib/mongo/auth/aws/conversation.rb +0 -4
- data/lib/mongo/auth/aws/credentials_retriever.rb +3 -8
- data/lib/mongo/auth/base.rb +1 -1
- data/lib/mongo/auth/sasl_conversation_base.rb +1 -1
- data/lib/mongo/auth/scram_conversation_base.rb +1 -8
- data/lib/mongo/auth/stringprep.rb +1 -6
- data/lib/mongo/auth/user/view.rb +1 -1
- data/lib/mongo/bulk_write/combineable.rb +0 -7
- data/lib/mongo/bulk_write/result_combiner.rb +3 -3
- data/lib/mongo/bulk_write/validatable.rb +0 -4
- data/lib/mongo/bulk_write.rb +1 -35
- data/lib/mongo/client.rb +117 -17
- data/lib/mongo/client_encryption.rb +36 -11
- data/lib/mongo/cluster/reapers/cursor_reaper.rb +12 -5
- data/lib/mongo/cluster/sdam_flow.rb +4 -4
- data/lib/mongo/cluster/topology/base.rb +1 -1
- data/lib/mongo/cluster.rb +13 -30
- data/lib/mongo/collection/queryable_encryption.rb +7 -6
- data/lib/mongo/collection/view/aggregation/behavior.rb +1 -1
- data/lib/mongo/collection/view/aggregation.rb +2 -4
- data/lib/mongo/collection/view/builder/aggregation.rb +3 -5
- data/lib/mongo/collection/view/builder/map_reduce.rb +1 -1
- data/lib/mongo/collection/view/change_stream.rb +14 -9
- data/lib/mongo/collection/view/map_reduce.rb +2 -11
- data/lib/mongo/collection/view/readable.rb +11 -7
- data/lib/mongo/collection/view/writable.rb +4 -39
- data/lib/mongo/collection/view.rb +8 -4
- data/lib/mongo/collection.rb +1 -1
- data/lib/mongo/crypt/auto_encrypter.rb +6 -2
- data/lib/mongo/crypt/binary.rb +7 -4
- data/lib/mongo/crypt/binding.rb +154 -11
- data/lib/mongo/crypt/context.rb +50 -19
- data/lib/mongo/crypt/encryption_io.rb +11 -5
- data/lib/mongo/crypt/explicit_encrypter.rb +27 -12
- data/lib/mongo/crypt/explicit_encryption_context.rb +51 -12
- data/lib/mongo/crypt/handle.rb +35 -5
- data/lib/mongo/crypt/kms/credentials.rb +70 -31
- data/lib/mongo/crypt/kms/kmip/master_document.rb +30 -1
- data/lib/mongo/crypt/kms/master_key_document.rb +11 -6
- data/lib/mongo/crypt/kms.rb +12 -1
- data/lib/mongo/cursor.rb +8 -2
- data/lib/mongo/database/cursor_command_view.rb +95 -0
- data/lib/mongo/database.rb +144 -18
- data/lib/mongo/error/invalid_uri.rb +5 -1
- data/lib/mongo/error/operation_failure.rb +2 -2
- data/lib/mongo/error/parser.rb +3 -3
- data/lib/mongo/error/sdam_error_detection.rb +2 -3
- data/lib/mongo/error/unsupported_option.rb +0 -40
- data/lib/mongo/grid/fs_bucket.rb +29 -23
- data/lib/mongo/grid/stream/read.rb +2 -2
- data/lib/mongo/grid/stream/write.rb +3 -3
- data/lib/mongo/index/view.rb +13 -7
- data/lib/mongo/monitoring/event/cmap/connection_check_out_failed.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/connection_check_out_started.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/connection_checked_in.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/connection_checked_out.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/connection_closed.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/connection_created.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/connection_ready.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/pool_cleared.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/pool_closed.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/pool_created.rb +1 -0
- data/lib/mongo/monitoring/event/cmap/pool_ready.rb +1 -0
- data/lib/mongo/monitoring/event/command_failed.rb +1 -0
- data/lib/mongo/monitoring/event/command_started.rb +1 -0
- data/lib/mongo/monitoring/event/command_succeeded.rb +1 -0
- data/lib/mongo/monitoring/event/secure.rb +12 -17
- data/lib/mongo/monitoring/event/server_closed.rb +1 -0
- data/lib/mongo/monitoring/event/server_description_changed.rb +1 -0
- data/lib/mongo/monitoring/event/server_heartbeat_failed.rb +1 -0
- data/lib/mongo/monitoring/event/server_heartbeat_started.rb +1 -0
- data/lib/mongo/monitoring/event/server_heartbeat_succeeded.rb +1 -0
- data/lib/mongo/monitoring/event/server_opening.rb +1 -0
- data/lib/mongo/monitoring/event/topology_changed.rb +1 -0
- data/lib/mongo/monitoring/event/topology_closed.rb +1 -0
- data/lib/mongo/monitoring/event/topology_opening.rb +1 -0
- data/lib/mongo/operation/create/op_msg.rb +1 -0
- data/lib/mongo/operation/create_index/op_msg.rb +2 -1
- data/lib/mongo/operation/cursor_command/op_msg.rb +37 -0
- data/lib/mongo/operation/cursor_command/result.rb +60 -0
- data/lib/mongo/operation/cursor_command.rb +33 -0
- data/lib/mongo/operation/delete/op_msg.rb +1 -0
- data/lib/mongo/operation/drop/op_msg.rb +1 -0
- data/lib/mongo/operation/drop_database/op_msg.rb +1 -0
- data/lib/mongo/operation/drop_index/op_msg.rb +1 -0
- data/lib/mongo/operation/find/builder/command.rb +1 -1
- data/lib/mongo/operation/insert/bulk_result.rb +2 -4
- data/lib/mongo/operation/insert/op_msg.rb +1 -0
- data/lib/mongo/operation/result.rb +21 -25
- data/lib/mongo/operation/shared/causal_consistency_supported.rb +4 -2
- data/lib/mongo/operation/shared/executable.rb +2 -15
- data/lib/mongo/operation/shared/result/aggregatable.rb +2 -2
- data/lib/mongo/operation/shared/sessions_supported.rb +3 -5
- data/lib/mongo/operation/update/bulk_result.rb +1 -1
- data/lib/mongo/operation/update/op_msg.rb +1 -0
- data/lib/mongo/operation/write_command/op_msg.rb +2 -0
- data/lib/mongo/operation.rb +1 -0
- data/lib/mongo/options/redacted.rb +2 -2
- data/lib/mongo/protocol/compressed.rb +15 -11
- data/lib/mongo/protocol/message.rb +16 -20
- data/lib/mongo/protocol/msg.rb +1 -12
- data/lib/mongo/protocol/registry.rb +1 -1
- data/lib/mongo/protocol/serializers.rb +1 -3
- data/lib/mongo/query_cache.rb +3 -5
- data/lib/mongo/retryable/backpressure.rb +17 -2
- data/lib/mongo/retryable/read_worker.rb +1 -1
- data/lib/mongo/retryable/retry_policy.rb +2 -2
- data/lib/mongo/retryable/write_worker.rb +2 -2
- data/lib/mongo/retryable.rb +1 -1
- data/lib/mongo/server/app_metadata.rb +1 -1
- data/lib/mongo/server/connection.rb +3 -1
- data/lib/mongo/server/connection_common.rb +9 -1
- data/lib/mongo/server/connection_pool/generation_manager.rb +1 -1
- data/lib/mongo/server/connection_pool.rb +24 -10
- data/lib/mongo/server/description/features.rb +1 -2
- data/lib/mongo/server/description.rb +1 -2
- data/lib/mongo/server/monitor/connection.rb +3 -2
- data/lib/mongo/server/monitor.rb +133 -30
- data/lib/mongo/server/pending_connection.rb +1 -5
- data/lib/mongo/server/push_monitor.rb +16 -2
- data/lib/mongo/server.rb +28 -9
- data/lib/mongo/server_selector/base.rb +3 -6
- data/lib/mongo/server_selector/secondary_preferred.rb +4 -1
- data/lib/mongo/session.rb +25 -26
- data/lib/mongo/socket/ssl.rb +3 -3
- data/lib/mongo/socket.rb +1 -7
- data/lib/mongo/srv/monitor.rb +11 -2
- data/lib/mongo/srv/resolver.rb +1 -1
- data/lib/mongo/srv/result.rb +5 -3
- data/lib/mongo/timeout.rb +10 -15
- data/lib/mongo/tracing/open_telemetry/command_tracer.rb +16 -2
- data/lib/mongo/uri/options_mapper.rb +36 -13
- data/lib/mongo/uri/srv_protocol.rb +4 -4
- data/lib/mongo/uri.rb +56 -8
- data/lib/mongo/utils.rb +1 -1
- data/lib/mongo/version.rb +1 -1
- metadata +6 -4
- data/lib/mongo/auth/stringprep/unicode_normalize/normalize.rb +0 -173
- data/lib/mongo/auth/stringprep/unicode_normalize/tables.rb +0 -1164
|
@@ -101,7 +101,7 @@ module Mongo
|
|
|
101
101
|
#
|
|
102
102
|
# @api private
|
|
103
103
|
def read_scheduled_kill_specs
|
|
104
|
-
while kill_spec = @kill_spec_queue.pop(true)
|
|
104
|
+
while (kill_spec = @kill_spec_queue.pop(true))
|
|
105
105
|
if @active_cursor_ids.include?(kill_spec.cursor_id)
|
|
106
106
|
@to_kill[kill_spec.server_address] ||= Set.new
|
|
107
107
|
@to_kill[kill_spec.server_address] << kill_spec
|
|
@@ -188,14 +188,21 @@ module Mongo
|
|
|
188
188
|
server_api: server.options[:server_api],
|
|
189
189
|
connection_global_id: kill_spec.connection_global_id,
|
|
190
190
|
}
|
|
191
|
-
if connection = kill_spec.connection
|
|
192
|
-
|
|
193
|
-
|
|
191
|
+
if (connection = kill_spec.connection)
|
|
192
|
+
begin
|
|
193
|
+
op.execute_with_connection(connection, context: Operation::Context.new(options: options))
|
|
194
|
+
rescue Error::SocketError, Error::SocketTimeoutError, Error::ConnectionPerished
|
|
195
|
+
# Connection is dead. do_check_in will detect connection.error?
|
|
196
|
+
# and disconnect it; the pool slot becomes free for a new connection.
|
|
197
|
+
ensure
|
|
198
|
+
connection.unpin(:cursor)
|
|
199
|
+
connection.connection_pool.check_in(connection) unless connection.pinned?
|
|
200
|
+
end
|
|
194
201
|
else
|
|
195
202
|
op.execute(server, context: Operation::Context.new(options: options))
|
|
196
203
|
end
|
|
197
204
|
|
|
198
|
-
next unless session = kill_spec.session
|
|
205
|
+
next unless (session = kill_spec.session)
|
|
199
206
|
|
|
200
207
|
session.end_session if session.implicit?
|
|
201
208
|
end
|
|
@@ -385,8 +385,8 @@ class Mongo::Cluster
|
|
|
385
385
|
def add_servers_from_desc(updated_desc)
|
|
386
386
|
added_servers = []
|
|
387
387
|
%w[hosts passives arbiters].each do |m|
|
|
388
|
-
updated_desc.
|
|
389
|
-
if server = cluster.add(address_str, monitor: false)
|
|
388
|
+
updated_desc.public_send(m).each do |address_str|
|
|
389
|
+
if (server = cluster.add(address_str, monitor: false))
|
|
390
390
|
added_servers << server
|
|
391
391
|
end
|
|
392
392
|
end
|
|
@@ -402,7 +402,7 @@ class Mongo::Cluster
|
|
|
402
402
|
# good primary).
|
|
403
403
|
def remove_servers_not_in_desc(updated_desc)
|
|
404
404
|
updated_desc_address_strs = %w[hosts passives arbiters].map do |m|
|
|
405
|
-
updated_desc.
|
|
405
|
+
updated_desc.public_send(m)
|
|
406
406
|
end.flatten
|
|
407
407
|
servers_list.each do |server|
|
|
408
408
|
next if updated_desc_address_strs.include?(address_str = server.address.to_s)
|
|
@@ -541,7 +541,7 @@ class Mongo::Cluster
|
|
|
541
541
|
end
|
|
542
542
|
|
|
543
543
|
def disconnect_servers
|
|
544
|
-
while server = @servers_to_disconnect.shift
|
|
544
|
+
while (server = @servers_to_disconnect.shift)
|
|
545
545
|
if server.connected?
|
|
546
546
|
# Do not publish server closed event, as this was already done
|
|
547
547
|
server.disconnect!
|
|
@@ -85,7 +85,7 @@ module Mongo
|
|
|
85
85
|
# LST is only read from data-bearing servers
|
|
86
86
|
if desc.data_bearing?
|
|
87
87
|
@have_data_bearing_servers = true
|
|
88
|
-
break unless timeout = desc.logical_session_timeout
|
|
88
|
+
break unless (timeout = desc.logical_session_timeout)
|
|
89
89
|
|
|
90
90
|
[ timeout, min || timeout ].min
|
|
91
91
|
else
|
data/lib/mongo/cluster.rb
CHANGED
|
@@ -269,30 +269,6 @@ module Mongo
|
|
|
269
269
|
start_stop_srv_monitor
|
|
270
270
|
end
|
|
271
271
|
|
|
272
|
-
# Create a cluster for the provided client, for use when we don't want the
|
|
273
|
-
# client's original cluster instance to be the same.
|
|
274
|
-
#
|
|
275
|
-
# @example Create a cluster for the client.
|
|
276
|
-
# Cluster.create(client)
|
|
277
|
-
#
|
|
278
|
-
# @param [ Client ] client The client to create on.
|
|
279
|
-
# @param [ Monitoring | nil ] monitoring. The monitoring instance to use
|
|
280
|
-
# with the new cluster. If nil, a new instance of Monitoring will be
|
|
281
|
-
# created.
|
|
282
|
-
#
|
|
283
|
-
# @return [ Cluster ] The cluster.
|
|
284
|
-
#
|
|
285
|
-
# @since 2.0.0
|
|
286
|
-
# @api private
|
|
287
|
-
def self.create(client, monitoring: nil)
|
|
288
|
-
cluster = Cluster.new(
|
|
289
|
-
client.cluster.addresses.map(&:to_s),
|
|
290
|
-
monitoring || Monitoring.new,
|
|
291
|
-
client.cluster_options
|
|
292
|
-
)
|
|
293
|
-
client.instance_variable_set(:@cluster, cluster)
|
|
294
|
-
end
|
|
295
|
-
|
|
296
272
|
# @return [ Hash ] The options hash.
|
|
297
273
|
attr_reader :options
|
|
298
274
|
|
|
@@ -324,9 +300,7 @@ module Mongo
|
|
|
324
300
|
# @api private
|
|
325
301
|
attr_reader :seeds
|
|
326
302
|
|
|
327
|
-
# @private
|
|
328
|
-
#
|
|
329
|
-
# @since 2.5.1
|
|
303
|
+
# @api private
|
|
330
304
|
attr_reader :session_pool
|
|
331
305
|
|
|
332
306
|
def_delegators :topology, :replica_set?, :replica_set_name, :sharded?,
|
|
@@ -612,8 +586,7 @@ module Mongo
|
|
|
612
586
|
# @option options [ true | false ] :keep_connection_pool Usually when the
|
|
613
587
|
# new server description is unknown, the connection pool on the
|
|
614
588
|
# respective server is cleared. Set this option to true to keep the
|
|
615
|
-
# existing connection pool (required when handling not master errors
|
|
616
|
-
# on 4.2+ servers).
|
|
589
|
+
# existing connection pool (required when handling not master errors).
|
|
617
590
|
# @option options [ true | false ] :awaited Whether the updated description
|
|
618
591
|
# was a result of processing an awaited hello.
|
|
619
592
|
# @option options [ Object ] :service_id Change state for the specified
|
|
@@ -802,7 +775,7 @@ module Mongo
|
|
|
802
775
|
#
|
|
803
776
|
# @since 2.5.0
|
|
804
777
|
def update_cluster_time(result)
|
|
805
|
-
return unless cluster_time_doc = result.cluster_time
|
|
778
|
+
return unless (cluster_time_doc = result.cluster_time)
|
|
806
779
|
|
|
807
780
|
@cluster_time_lock.synchronize do
|
|
808
781
|
advance_cluster_time(cluster_time_doc)
|
|
@@ -983,6 +956,16 @@ module Mongo
|
|
|
983
956
|
end
|
|
984
957
|
end
|
|
985
958
|
|
|
959
|
+
# Forces the cluster's periodic executor to run immediately. If the cluster
|
|
960
|
+
# has no periodic executor, this method does nothing.
|
|
961
|
+
#
|
|
962
|
+
# @api private
|
|
963
|
+
def trigger_periodic_executor!
|
|
964
|
+
return unless @periodic_executor
|
|
965
|
+
|
|
966
|
+
@periodic_executor.execute
|
|
967
|
+
end
|
|
968
|
+
|
|
986
969
|
private
|
|
987
970
|
|
|
988
971
|
# @api private
|
|
@@ -62,8 +62,8 @@ module Mongo
|
|
|
62
62
|
def maybe_drop_emm_collections(encrypted_fields, client, session)
|
|
63
63
|
encrypted_fields = if encrypted_fields
|
|
64
64
|
encrypted_fields
|
|
65
|
-
elsif
|
|
66
|
-
|
|
65
|
+
elsif client.options[:auto_encryption_options]
|
|
66
|
+
encrypted_fields_for_drop
|
|
67
67
|
else
|
|
68
68
|
{}
|
|
69
69
|
end
|
|
@@ -127,12 +127,13 @@ module Mongo
|
|
|
127
127
|
{}
|
|
128
128
|
end
|
|
129
129
|
|
|
130
|
-
# Tries to return the encrypted fields
|
|
131
|
-
# value,
|
|
130
|
+
# Tries to return the encrypted fields for the current namespace from
|
|
131
|
+
# the {{encrypted_fields_map}} value, falling back to the encrypted
|
|
132
|
+
# fields advertised by the server for the collection.
|
|
132
133
|
#
|
|
133
134
|
# @return [ Hash | nil ] the encrypted fields, if found
|
|
134
|
-
def
|
|
135
|
-
encrypted_fields_map[namespace] ||
|
|
135
|
+
def encrypted_fields_for_drop
|
|
136
|
+
(encrypted_fields_map && encrypted_fields_map[namespace]) ||
|
|
136
137
|
database.list_collections(filter: { name: name })
|
|
137
138
|
.first
|
|
138
139
|
&.fetch(:options, {})
|
|
@@ -104,10 +104,8 @@ module Mongo
|
|
|
104
104
|
|
|
105
105
|
primary_read_preference = { mode: :primary }
|
|
106
106
|
description = connection.description
|
|
107
|
-
if description.primary?
|
|
108
|
-
|
|
109
|
-
primary_read_preference
|
|
110
|
-
elsif description.mongos? && !description.features.merge_out_on_secondary_enabled?
|
|
107
|
+
if description.primary? ||
|
|
108
|
+
(description.mongos? && !description.features.merge_out_on_secondary_enabled?)
|
|
111
109
|
log_warn('Routing the Aggregation operation to the primary server')
|
|
112
110
|
primary_read_preference
|
|
113
111
|
else
|
|
@@ -105,7 +105,7 @@ module Mongo
|
|
|
105
105
|
raise ArgumentError, "Unknown view class: #{view}"
|
|
106
106
|
end
|
|
107
107
|
command[:pipeline] = pipeline
|
|
108
|
-
if read_concern = view.read_concern
|
|
108
|
+
if (read_concern = view.read_concern) && !read_concern.empty?
|
|
109
109
|
command[:readConcern] = Options::Mapper.transform_values_to_strings(
|
|
110
110
|
read_concern
|
|
111
111
|
)
|
|
@@ -117,12 +117,10 @@ module Mongo
|
|
|
117
117
|
|
|
118
118
|
def batch_size_doc
|
|
119
119
|
value = options[:batch_size] || view.batch_size
|
|
120
|
-
if value == 0 && write?
|
|
120
|
+
if value.nil? || (value == 0 && write?)
|
|
121
121
|
{}
|
|
122
|
-
elsif value
|
|
123
|
-
{ batchSize: value }
|
|
124
122
|
else
|
|
125
|
-
{}
|
|
123
|
+
{ batchSize: value }
|
|
126
124
|
end
|
|
127
125
|
end
|
|
128
126
|
end
|
|
@@ -351,19 +351,24 @@ module Mongo
|
|
|
351
351
|
# In load balanced topology, manually check out a connection
|
|
352
352
|
# so it remains checked out and pinned to the cursor.
|
|
353
353
|
connection = server.pool.check_out(context: context)
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
354
|
+
begin
|
|
355
|
+
result = send_initial_query(connection, context)
|
|
356
|
+
|
|
357
|
+
start_at_operation_time = if (doc = result.replies.first && result.replies.first.documents.first)
|
|
358
|
+
doc['operationTime']
|
|
359
|
+
else
|
|
360
|
+
nil
|
|
361
|
+
end
|
|
362
|
+
result
|
|
363
|
+
rescue StandardError
|
|
364
|
+
server.pool.check_in(connection)
|
|
365
|
+
raise
|
|
366
|
+
end
|
|
362
367
|
else
|
|
363
368
|
server.with_connection do |connection|
|
|
364
369
|
result = send_initial_query(connection, context)
|
|
365
370
|
|
|
366
|
-
start_at_operation_time = if doc = result.replies.first && result.replies.first.documents.first
|
|
371
|
+
start_at_operation_time = if (doc = result.replies.first && result.replies.first.documents.first)
|
|
367
372
|
doc['operationTime']
|
|
368
373
|
else
|
|
369
374
|
# The above may set @start_at_operation_time to nil
|
|
@@ -227,7 +227,7 @@ module Mongo
|
|
|
227
227
|
#
|
|
228
228
|
# @since 2.5.0
|
|
229
229
|
def execute
|
|
230
|
-
view.
|
|
230
|
+
view.with_session(@options) do |session|
|
|
231
231
|
write_concern = view.write_concern_with_session(session)
|
|
232
232
|
context = Operation::Context.new(client: client, session: session)
|
|
233
233
|
nro_write_with_retry(write_concern, context: context) do |connection, _txn_num, context|
|
|
@@ -241,7 +241,7 @@ module Mongo
|
|
|
241
241
|
OUT_ACTIONS = %i[replace merge reduce].freeze
|
|
242
242
|
|
|
243
243
|
def server_selector
|
|
244
|
-
@view.
|
|
244
|
+
@view.server_selector
|
|
245
245
|
end
|
|
246
246
|
|
|
247
247
|
def inline?
|
|
@@ -299,15 +299,6 @@ module Mongo
|
|
|
299
299
|
end
|
|
300
300
|
end
|
|
301
301
|
|
|
302
|
-
def fetch_query_spec
|
|
303
|
-
Builder::MapReduce.new(map_function, reduce_function, view, options).query_specification
|
|
304
|
-
end
|
|
305
|
-
|
|
306
|
-
def find_command_spec(session)
|
|
307
|
-
Builder::MapReduce.new(map_function, reduce_function, view,
|
|
308
|
-
options.merge(session: session)).command_specification
|
|
309
|
-
end
|
|
310
|
-
|
|
311
302
|
def fetch_query_op(session)
|
|
312
303
|
spec = {
|
|
313
304
|
coll_name: out_collection_name,
|
|
@@ -678,7 +678,7 @@ module Mongo
|
|
|
678
678
|
# @api private
|
|
679
679
|
def read_concern
|
|
680
680
|
if options[:session] && options[:session].in_transaction?
|
|
681
|
-
options[:session].
|
|
681
|
+
options[:session].txn_read_concern || collection.client.read_concern
|
|
682
682
|
else
|
|
683
683
|
collection.read_concern
|
|
684
684
|
end
|
|
@@ -749,12 +749,10 @@ module Mongo
|
|
|
749
749
|
end
|
|
750
750
|
end
|
|
751
751
|
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
end
|
|
757
|
-
|
|
752
|
+
# The server selector for this view, derived from its read
|
|
753
|
+
# preference (or the collection/client default).
|
|
754
|
+
#
|
|
755
|
+
# @api private
|
|
758
756
|
def server_selector
|
|
759
757
|
@server_selector ||= if options[:session] && options[:session].in_transaction?
|
|
760
758
|
ServerSelector.get(read_preference || client.server_selector)
|
|
@@ -763,6 +761,12 @@ module Mongo
|
|
|
763
761
|
end
|
|
764
762
|
end
|
|
765
763
|
|
|
764
|
+
private
|
|
765
|
+
|
|
766
|
+
def collation(doc = nil)
|
|
767
|
+
configure(:collation, doc)
|
|
768
|
+
end
|
|
769
|
+
|
|
766
770
|
def validate_doc!(doc)
|
|
767
771
|
raise Error::InvalidDocument.new unless doc.respond_to?(:keys)
|
|
768
772
|
end
|
|
@@ -88,11 +88,6 @@ module Mongo
|
|
|
88
88
|
operation_timeouts: operation_timeouts(opts)
|
|
89
89
|
)
|
|
90
90
|
write_with_retry(write_concern, context: context) do |connection, txn_num, context|
|
|
91
|
-
gte_4_4 = connection.server.description.server_version_gte?('4.4')
|
|
92
|
-
if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged?
|
|
93
|
-
raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
91
|
Operation::WriteCommand.new(
|
|
97
92
|
selector: cmd,
|
|
98
93
|
db_name: database.name,
|
|
@@ -216,11 +211,6 @@ module Mongo
|
|
|
216
211
|
)
|
|
217
212
|
value = tracer.trace_operation(operation, context, op_name: 'findOneAndUpdate') do
|
|
218
213
|
write_with_retry(write_concern, context: context) do |connection, txn_num, context|
|
|
219
|
-
gte_4_4 = connection.server.description.server_version_gte?('4.4')
|
|
220
|
-
if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged?
|
|
221
|
-
raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
|
|
222
|
-
end
|
|
223
|
-
|
|
224
214
|
operation.txn_num = txn_num
|
|
225
215
|
operation.execute_with_connection(connection, context: context)
|
|
226
216
|
end
|
|
@@ -287,11 +277,6 @@ module Mongo
|
|
|
287
277
|
)
|
|
288
278
|
tracer.trace_operation(operation, context, op_name: 'deleteMany') do
|
|
289
279
|
nro_write_with_retry(write_concern, context: context) do |connection, _txn_num, context|
|
|
290
|
-
gte_4_4 = connection.server.description.server_version_gte?('4.4')
|
|
291
|
-
if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged?
|
|
292
|
-
raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
|
|
293
|
-
end
|
|
294
|
-
|
|
295
280
|
operation.execute_with_connection(connection, context: context)
|
|
296
281
|
end
|
|
297
282
|
end
|
|
@@ -346,11 +331,6 @@ module Mongo
|
|
|
346
331
|
operation_timeouts: operation_timeouts(opts)
|
|
347
332
|
)
|
|
348
333
|
write_with_retry(write_concern, context: context) do |connection, txn_num, context|
|
|
349
|
-
gte_4_4 = connection.server.description.server_version_gte?('4.4')
|
|
350
|
-
if !gte_4_4 && opts[:hint] && write_concern && !write_concern.acknowledged?
|
|
351
|
-
raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
|
|
352
|
-
end
|
|
353
|
-
|
|
354
334
|
Operation::Delete.new(
|
|
355
335
|
deletes: [ delete_doc ],
|
|
356
336
|
db_name: collection.database.name,
|
|
@@ -428,11 +408,6 @@ module Mongo
|
|
|
428
408
|
operation_timeouts: operation_timeouts(opts)
|
|
429
409
|
)
|
|
430
410
|
write_with_retry(write_concern, context: context) do |connection, txn_num, context|
|
|
431
|
-
gte_4_2 = connection.server.description.server_version_gte?('4.2')
|
|
432
|
-
if !gte_4_2 && opts[:hint] && write_concern && !write_concern.acknowledged?
|
|
433
|
-
raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
|
|
434
|
-
end
|
|
435
|
-
|
|
436
411
|
Operation::Update.new(
|
|
437
412
|
updates: [ update_doc ],
|
|
438
413
|
db_name: collection.database.name,
|
|
@@ -507,11 +482,6 @@ module Mongo
|
|
|
507
482
|
operation_timeouts: operation_timeouts(opts)
|
|
508
483
|
)
|
|
509
484
|
nro_write_with_retry(write_concern, context: context) do |connection, _txn_num, context|
|
|
510
|
-
gte_4_2 = connection.server.description.server_version_gte?('4.2')
|
|
511
|
-
if !gte_4_2 && opts[:hint] && write_concern && !write_concern.acknowledged?
|
|
512
|
-
raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
|
|
513
|
-
end
|
|
514
|
-
|
|
515
485
|
Operation::Update.new(
|
|
516
486
|
updates: [ update_doc ],
|
|
517
487
|
db_name: collection.database.name,
|
|
@@ -601,11 +571,6 @@ module Mongo
|
|
|
601
571
|
)
|
|
602
572
|
tracer.trace_operation(operation, context) do
|
|
603
573
|
write_with_retry(write_concern, context: context) do |connection, txn_num, context|
|
|
604
|
-
gte_4_2 = connection.server.description.server_version_gte?('4.2')
|
|
605
|
-
if !gte_4_2 && opts[:hint] && write_concern && !write_concern.acknowledged?
|
|
606
|
-
raise Error::UnsupportedOption.hint_error(unacknowledged_write: true)
|
|
607
|
-
end
|
|
608
|
-
|
|
609
574
|
operation.txn_num = txn_num
|
|
610
575
|
operation.execute_with_connection(connection, context: context)
|
|
611
576
|
end
|
|
@@ -624,8 +589,8 @@ module Mongo
|
|
|
624
589
|
# @raise [ Error::InvalidUpdateDocument ] if the first key in the
|
|
625
590
|
# document does not start with a $.
|
|
626
591
|
def validate_update_documents!(spec)
|
|
627
|
-
return unless update = spec.is_a?(Array) ? spec&.first : spec
|
|
628
|
-
return unless key = update.keys&.first
|
|
592
|
+
return unless (update = spec.is_a?(Array) ? spec&.first : spec)
|
|
593
|
+
return unless (key = update.keys&.first)
|
|
629
594
|
return if key.to_s.start_with?('$')
|
|
630
595
|
raise Error::InvalidUpdateDocument.new(key: key) if Mongo.validate_update_replace
|
|
631
596
|
|
|
@@ -641,8 +606,8 @@ module Mongo
|
|
|
641
606
|
# @raise [ Error::InvalidUpdateDocument ] if the first key in the
|
|
642
607
|
# document does not start with a $.
|
|
643
608
|
def validate_replacement_documents!(spec)
|
|
644
|
-
return unless replace = spec.is_a?(Array) ? spec&.first : spec
|
|
645
|
-
return unless key = replace.keys&.first
|
|
609
|
+
return unless (replace = spec.is_a?(Array) ? spec&.first : spec)
|
|
610
|
+
return unless (key = replace.keys&.first)
|
|
646
611
|
return unless key.to_s.start_with?('$')
|
|
647
612
|
raise Error::InvalidReplacementDocument.new(key: key) if Mongo.validate_update_replace
|
|
648
613
|
|
|
@@ -236,6 +236,14 @@ module Mongo
|
|
|
236
236
|
end
|
|
237
237
|
end
|
|
238
238
|
|
|
239
|
+
# Executes the provided block within the context of a session, using
|
|
240
|
+
# this view's options merged with the given ones.
|
|
241
|
+
#
|
|
242
|
+
# @api private
|
|
243
|
+
def with_session(opts = {}, &block)
|
|
244
|
+
client.with_session(@options.merge(opts), &block)
|
|
245
|
+
end
|
|
246
|
+
|
|
239
247
|
private
|
|
240
248
|
|
|
241
249
|
def initialize_copy(other)
|
|
@@ -252,10 +260,6 @@ module Mongo
|
|
|
252
260
|
def view
|
|
253
261
|
self
|
|
254
262
|
end
|
|
255
|
-
|
|
256
|
-
def with_session(opts = {}, &block)
|
|
257
|
-
client.with_session(@options.merge(opts), &block)
|
|
258
|
-
end
|
|
259
263
|
end
|
|
260
264
|
end
|
|
261
265
|
end
|
data/lib/mongo/collection.rb
CHANGED
|
@@ -393,7 +393,7 @@ module Mongo
|
|
|
393
393
|
operation = { create: name }.merge(options)
|
|
394
394
|
operation.delete(:write)
|
|
395
395
|
operation.delete(:write_concern)
|
|
396
|
-
client.
|
|
396
|
+
client.with_session(opts) do |session|
|
|
397
397
|
write_concern = if opts[:write_concern]
|
|
398
398
|
WriteConcern.get(opts[:write_concern])
|
|
399
399
|
else
|
|
@@ -81,6 +81,9 @@ module Mongo
|
|
|
81
81
|
# @option options [ Boolean | nil ] :crypt_shared_lib_required Whether
|
|
82
82
|
# crypt shared library is required. If 'true', an error will be raised
|
|
83
83
|
# if a crypt_shared library cannot be loaded by libmongocrypt.
|
|
84
|
+
# @option options [ Integer | nil ] :key_expiration_ms The lifetime of the
|
|
85
|
+
# data encryption key cache, in milliseconds. A value of 0 means the
|
|
86
|
+
# cache never expires. Defaults to 60000.
|
|
84
87
|
#
|
|
85
88
|
# @raise [ ArgumentError ] If required options are missing or incorrectly
|
|
86
89
|
# formatted.
|
|
@@ -99,7 +102,8 @@ module Mongo
|
|
|
99
102
|
bypass_query_analysis: @options[:bypass_query_analysis],
|
|
100
103
|
crypt_shared_lib_path: @options[:extra_options][:crypt_shared_lib_path],
|
|
101
104
|
crypt_shared_lib_required: @options[:extra_options][:crypt_shared_lib_required],
|
|
102
|
-
disable_crypt_shared_lib_search: @options[:extra_options][:disable_crypt_shared_lib_search]
|
|
105
|
+
disable_crypt_shared_lib_search: @options[:extra_options][:disable_crypt_shared_lib_search],
|
|
106
|
+
key_expiration_ms: @options[:key_expiration_ms]
|
|
103
107
|
)
|
|
104
108
|
|
|
105
109
|
@mongocryptd_options = @options[:extra_options].slice(
|
|
@@ -287,7 +291,7 @@ module Mongo
|
|
|
287
291
|
@internal_client ||= client.with(
|
|
288
292
|
auto_encryption_options: nil,
|
|
289
293
|
min_pool_size: 0,
|
|
290
|
-
monitoring: client.
|
|
294
|
+
monitoring: client.monitoring
|
|
291
295
|
)
|
|
292
296
|
end
|
|
293
297
|
end
|
data/lib/mongo/crypt/binary.rb
CHANGED
|
@@ -139,14 +139,17 @@ module Mongo
|
|
|
139
139
|
# Wraps a String with a mongocrypt_binary_t, yielding an FFI::Pointer
|
|
140
140
|
# to the wrapped struct.
|
|
141
141
|
def self.wrap_string(str)
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
142
|
+
# mongocrypt_binary_new_from_data does not copy the buffer, so the
|
|
143
|
+
# MemoryPointer must outlive the mongocrypt_binary_t. Hold it in a
|
|
144
|
+
# local so it stays referenced for the whole method frame; otherwise
|
|
145
|
+
# GC can free the buffer while libmongocrypt still points into it.
|
|
146
|
+
data_p = FFI::MemoryPointer.from_string(str)
|
|
147
|
+
binary_p = Binding.mongocrypt_binary_new_from_data(data_p, str.bytesize)
|
|
146
148
|
begin
|
|
147
149
|
yield binary_p
|
|
148
150
|
ensure
|
|
149
151
|
Binding.mongocrypt_binary_destroy(binary_p)
|
|
152
|
+
data_p # rubocop:disable Lint/Void -- keep the buffer alive past destroy
|
|
150
153
|
end
|
|
151
154
|
end
|
|
152
155
|
end
|