mongo 2.24.1 → 2.25.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/result_combiner.rb +3 -3
- data/lib/mongo/bulk_write.rb +1 -1
- data/lib/mongo/client.rb +82 -12
- 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 +12 -28
- 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 -4
- data/lib/mongo/collection/view.rb +8 -4
- data/lib/mongo/collection.rb +1 -1
- data/lib/mongo/crypt/auto_encrypter.rb +1 -1
- data/lib/mongo/crypt/binary.rb +7 -4
- data/lib/mongo/crypt/binding.rb +88 -10
- data/lib/mongo/crypt/context.rb +50 -19
- data/lib/mongo/crypt/encryption_io.rb +11 -5
- data/lib/mongo/crypt/handle.rb +17 -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/grid/fs_bucket.rb +27 -21
- data/lib/mongo/grid/stream/write.rb +2 -2
- 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 +12 -25
- data/lib/mongo/operation/shared/causal_consistency_supported.rb +4 -2
- data/lib/mongo/operation/shared/executable.rb +1 -9
- 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 -16
- 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/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 -1
- data/lib/mongo/server/description.rb +1 -1
- 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 -0
- data/lib/mongo/server/push_monitor.rb +16 -2
- data/lib/mongo/server.rb +27 -7
- data/lib/mongo/server_selector/base.rb +3 -6
- data/lib/mongo/server_selector/secondary_preferred.rb +4 -1
- data/lib/mongo/session.rb +22 -23
- 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 +21 -9
- 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
|
@@ -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
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
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
|
-
|
|
82
|
-
|
|
83
|
-
|
|
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
|
|
@@ -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
|
|
@@ -47,11 +47,9 @@ module Mongo
|
|
|
47
47
|
# @since 2.0.0
|
|
48
48
|
# @api private
|
|
49
49
|
def initialize(replies, connection_description, connection_global_id, ids)
|
|
50
|
-
|
|
51
|
-
@connection_description = connection_description
|
|
52
|
-
@connection_global_id = connection_global_id
|
|
50
|
+
super(replies, connection_description, connection_global_id)
|
|
53
51
|
if replies && replies.first && (doc = replies.first.documents.first)
|
|
54
|
-
if errors = doc['writeErrors']
|
|
52
|
+
if (errors = doc['writeErrors'])
|
|
55
53
|
# some documents were potentially inserted
|
|
56
54
|
bad_indices = {}
|
|
57
55
|
errors.map do |error|
|
|
@@ -162,15 +162,6 @@ module Mongo
|
|
|
162
162
|
!!@replies
|
|
163
163
|
end
|
|
164
164
|
|
|
165
|
-
# Whether the result contains cursor_id
|
|
166
|
-
#
|
|
167
|
-
# @return [ true, false ] If the result contains cursor_id.
|
|
168
|
-
#
|
|
169
|
-
# @api private
|
|
170
|
-
def has_cursor_id?
|
|
171
|
-
acknowledged? && replies.last.respond_to?(:cursor_id)
|
|
172
|
-
end
|
|
173
|
-
|
|
174
165
|
# Get the cursor id if the response is acknowledged.
|
|
175
166
|
#
|
|
176
167
|
# @note Cursor ids of 0 indicate there is no cursor on the server.
|
|
@@ -183,7 +174,17 @@ module Mongo
|
|
|
183
174
|
# @since 2.0.0
|
|
184
175
|
# @api private
|
|
185
176
|
def cursor_id
|
|
186
|
-
|
|
177
|
+
return 0 unless acknowledged?
|
|
178
|
+
|
|
179
|
+
if replies.last.respond_to?(:cursor_id)
|
|
180
|
+
# Legacy OP_REPLY replies expose the cursor id directly.
|
|
181
|
+
replies.last.cursor_id
|
|
182
|
+
elsif first_document.key?(CURSOR)
|
|
183
|
+
# OP_MSG command replies carry the cursor id in the `cursor` subdocument.
|
|
184
|
+
first_document[CURSOR][CURSOR_ID] || 0
|
|
185
|
+
else
|
|
186
|
+
0
|
|
187
|
+
end
|
|
187
188
|
end
|
|
188
189
|
|
|
189
190
|
# Get the namespace of the cursor. The method should be defined in
|
|
@@ -450,7 +451,7 @@ module Mongo
|
|
|
450
451
|
end
|
|
451
452
|
|
|
452
453
|
def snapshot_timestamp
|
|
453
|
-
return unless doc = reply.documents.first
|
|
454
|
+
return unless (doc = reply.documents.first)
|
|
454
455
|
|
|
455
456
|
doc['cursor']&.[]('atClusterTime') || doc['atClusterTime']
|
|
456
457
|
end
|
|
@@ -465,20 +466,6 @@ module Mongo
|
|
|
465
466
|
end
|
|
466
467
|
end
|
|
467
468
|
|
|
468
|
-
def aggregate_returned_count
|
|
469
|
-
replies.reduce(0) do |n, reply|
|
|
470
|
-
n += reply.number_returned
|
|
471
|
-
n
|
|
472
|
-
end
|
|
473
|
-
end
|
|
474
|
-
|
|
475
|
-
def aggregate_written_count
|
|
476
|
-
documents.reduce(0) do |n, document|
|
|
477
|
-
n += document[N] || 0
|
|
478
|
-
n
|
|
479
|
-
end
|
|
480
|
-
end
|
|
481
|
-
|
|
482
469
|
def parser
|
|
483
470
|
@parser ||= Error::Parser.new(first_document, replies)
|
|
484
471
|
end
|
|
@@ -28,8 +28,10 @@ module Mongo
|
|
|
28
28
|
#
|
|
29
29
|
# This method overrides the causal consistency addition logic of
|
|
30
30
|
# SessionsSupported and is meant to be used with operations classified
|
|
31
|
-
# as "read operations accepting a read concern", as these are
|
|
32
|
-
# in the causal consistency spec.
|
|
31
|
+
# as "read and write operations accepting a read concern", as these are
|
|
32
|
+
# defined in the causal consistency spec. For write operations this
|
|
33
|
+
# attaches only afterClusterTime (no read concern level) so that causal
|
|
34
|
+
# ordering is preserved across writes in a causally consistent session.
|
|
33
35
|
#
|
|
34
36
|
# In order for the override to work correctly the
|
|
35
37
|
# CausalConsistencySupported module must be included after
|
|
@@ -64,14 +64,6 @@ module Mongo
|
|
|
64
64
|
end
|
|
65
65
|
end
|
|
66
66
|
|
|
67
|
-
if result.has_cursor_id? &&
|
|
68
|
-
connection.description.load_balancer?
|
|
69
|
-
if result.cursor_id == 0
|
|
70
|
-
connection.unpin
|
|
71
|
-
else
|
|
72
|
-
connection.pin
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
67
|
process_result(result, connection)
|
|
76
68
|
end
|
|
77
69
|
end
|
|
@@ -121,7 +113,7 @@ module Mongo
|
|
|
121
113
|
# @param [ Mongo::Operation::Context ] context The operation context.
|
|
122
114
|
def build_message(connection, context)
|
|
123
115
|
msg = message(connection)
|
|
124
|
-
if server_api = context.server_api
|
|
116
|
+
if (server_api = context.server_api)
|
|
125
117
|
msg = msg.maybe_add_server_api(server_api)
|
|
126
118
|
end
|
|
127
119
|
msg
|
|
@@ -36,7 +36,7 @@ module Mongo
|
|
|
36
36
|
return unless @replies
|
|
37
37
|
|
|
38
38
|
@replies.reduce(nil) do |errors, reply|
|
|
39
|
-
next unless write_errors = reply.documents.first['writeErrors']
|
|
39
|
+
next unless (write_errors = reply.documents.first['writeErrors'])
|
|
40
40
|
|
|
41
41
|
wes = write_errors.collect do |we|
|
|
42
42
|
we.merge!('index' => count + we['index'])
|
|
@@ -59,7 +59,7 @@ module Mongo
|
|
|
59
59
|
return unless @replies
|
|
60
60
|
|
|
61
61
|
@replies.each_with_index.reduce(nil) do |errors, (reply, _)|
|
|
62
|
-
next unless write_concern_errors = reply.documents.first['writeConcernErrors']
|
|
62
|
+
next unless (write_concern_errors = reply.documents.first['writeConcernErrors'])
|
|
63
63
|
|
|
64
64
|
(errors || []) << write_concern_errors.reduce(nil) do |errs, wce|
|
|
65
65
|
wce.merge!('index' => count + wce['index'])
|
|
@@ -61,7 +61,7 @@ module Mongo
|
|
|
61
61
|
def apply_causal_consistency_if_possible(selector, connection)
|
|
62
62
|
return if connection.description.standalone?
|
|
63
63
|
|
|
64
|
-
cc_doc = session.
|
|
64
|
+
cc_doc = session.causal_consistency_doc
|
|
65
65
|
return unless cc_doc
|
|
66
66
|
|
|
67
67
|
rc_doc = (selector[:readConcern] || read_concern || {}).merge(cc_doc)
|
|
@@ -165,9 +165,7 @@ module Mongo
|
|
|
165
165
|
read_doc = if connection.description.standalone?
|
|
166
166
|
# Read preference is never sent to standalones.
|
|
167
167
|
nil
|
|
168
|
-
elsif connection.server.load_balancer?
|
|
169
|
-
read&.to_mongos
|
|
170
|
-
elsif connection.description.mongos?
|
|
168
|
+
elsif connection.server.load_balancer? || connection.description.mongos?
|
|
171
169
|
# When server is a mongos:
|
|
172
170
|
# - $readPreference is never sent when mode is 'primary'
|
|
173
171
|
# - Otherwise $readPreference is sent
|
|
@@ -243,7 +241,7 @@ module Mongo
|
|
|
243
241
|
end
|
|
244
242
|
|
|
245
243
|
super.tap do |message|
|
|
246
|
-
if session = context.session
|
|
244
|
+
if (session = context.session)
|
|
247
245
|
# Serialize the message to detect client-side problems,
|
|
248
246
|
# such as invalid BSON keys or too large messages.
|
|
249
247
|
# The message will be serialized again
|
data/lib/mongo/operation.rb
CHANGED
|
@@ -38,6 +38,7 @@ require 'mongo/operation/drop'
|
|
|
38
38
|
require 'mongo/operation/drop_database'
|
|
39
39
|
require 'mongo/operation/get_more'
|
|
40
40
|
require 'mongo/operation/find'
|
|
41
|
+
require 'mongo/operation/cursor_command'
|
|
41
42
|
require 'mongo/operation/explain'
|
|
42
43
|
require 'mongo/operation/kill_cursors'
|
|
43
44
|
require 'mongo/operation/indexes'
|
|
@@ -143,14 +143,14 @@ module Mongo
|
|
|
143
143
|
|
|
144
144
|
def redacted_string(method)
|
|
145
145
|
'{' + reduce([]) do |list, (k, v)|
|
|
146
|
-
list << "#{k.
|
|
146
|
+
list << "#{k.public_send(method)}=>#{redact(k, v, method)}"
|
|
147
147
|
end.join(', ') + '}'
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
def redact(k, v, method)
|
|
151
151
|
return STRING_REPLACEMENT if SENSITIVE_OPTIONS.include?(k.to_sym)
|
|
152
152
|
|
|
153
|
-
v.
|
|
153
|
+
v.public_send(method)
|
|
154
154
|
end
|
|
155
155
|
end
|
|
156
156
|
end
|
|
@@ -74,12 +74,15 @@ module Mongo
|
|
|
74
74
|
#
|
|
75
75
|
# @since 2.5.0
|
|
76
76
|
def initialize(message, compressor, zlib_compression_level = nil)
|
|
77
|
+
super()
|
|
77
78
|
@original_message = message
|
|
78
79
|
@original_op_code = message.op_code
|
|
79
80
|
@uncompressed_size = 0
|
|
80
81
|
@compressor_id = COMPRESSOR_ID_MAP[compressor]
|
|
81
82
|
@compressed_message = ''
|
|
82
83
|
@zlib_compression_level = zlib_compression_level if zlib_compression_level && zlib_compression_level != -1
|
|
84
|
+
# A compressed message must reuse the wrapped message's request id,
|
|
85
|
+
# overriding the fresh id assigned by the superclass initializer.
|
|
83
86
|
@request_id = message.request_id
|
|
84
87
|
end
|
|
85
88
|
|
|
@@ -93,11 +96,11 @@ module Mongo
|
|
|
93
96
|
message = Registry.get(@original_op_code).allocate
|
|
94
97
|
buf = decompress(@compressed_message)
|
|
95
98
|
|
|
96
|
-
message.
|
|
99
|
+
message.fields.each do |field|
|
|
97
100
|
if field[:multi]
|
|
98
|
-
|
|
101
|
+
message.deserialize_array(buf, field)
|
|
99
102
|
else
|
|
100
|
-
|
|
103
|
+
message.deserialize_field(buf, field)
|
|
101
104
|
end
|
|
102
105
|
end
|
|
103
106
|
message.fix_after_deserialization if message.is_a?(Msg)
|
|
@@ -116,6 +119,15 @@ module Mongo
|
|
|
116
119
|
@original_message.replyable?
|
|
117
120
|
end
|
|
118
121
|
|
|
122
|
+
# @api private
|
|
123
|
+
def serialize_fields(buffer, max_bson_size)
|
|
124
|
+
buf = BSON::ByteBuffer.new
|
|
125
|
+
@original_message.serialize_fields(buf, max_bson_size)
|
|
126
|
+
@uncompressed_size = buf.length
|
|
127
|
+
@compressed_message = compress(buf)
|
|
128
|
+
super
|
|
129
|
+
end
|
|
130
|
+
|
|
119
131
|
private
|
|
120
132
|
|
|
121
133
|
# The operation code for a +Compressed+ message.
|
|
@@ -140,14 +152,6 @@ module Mongo
|
|
|
140
152
|
# @return [ String ] The actual compressed message bytes.
|
|
141
153
|
field :compressed_message, Bytes
|
|
142
154
|
|
|
143
|
-
def serialize_fields(buffer, max_bson_size)
|
|
144
|
-
buf = BSON::ByteBuffer.new
|
|
145
|
-
@original_message.send(:serialize_fields, buf, max_bson_size)
|
|
146
|
-
@uncompressed_size = buf.length
|
|
147
|
-
@compressed_message = compress(buf)
|
|
148
|
-
super
|
|
149
|
-
end
|
|
150
|
-
|
|
151
155
|
def compress(buffer)
|
|
152
156
|
if @compressor_id == NOOP_BYTE
|
|
153
157
|
buffer.to_s.force_encoding(BSON::BINARY)
|