mongo 2.18.1 → 2.18.3
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
- checksums.yaml.gz.sig +0 -0
- data/README.md +1 -1
- data/lib/mongo/bulk_write.rb +6 -4
- data/lib/mongo/client.rb +1 -1
- data/lib/mongo/collection/view/iterable.rb +15 -0
- data/lib/mongo/collection/view/writable.rb +0 -2
- data/lib/mongo/collection/view.rb +1 -0
- data/lib/mongo/collection.rb +150 -45
- data/lib/mongo/crypt/auto_encrypter.rb +1 -0
- data/lib/mongo/crypt/explicit_encrypter.rb +1 -0
- data/lib/mongo/crypt/kms.rb +0 -1
- data/lib/mongo/crypt.rb +11 -0
- data/lib/mongo/error/invalid_read_option.rb +1 -1
- data/lib/mongo/grid/file/chunk.rb +2 -1
- data/lib/mongo/grid/file/info.rb +2 -1
- data/lib/mongo/operation/aggregate.rb +1 -2
- data/lib/mongo/operation/collections_info.rb +3 -15
- data/lib/mongo/operation/command.rb +1 -2
- data/lib/mongo/operation/count.rb +1 -2
- data/lib/mongo/operation/create.rb +1 -2
- data/lib/mongo/operation/create_index.rb +1 -2
- data/lib/mongo/operation/create_user.rb +1 -2
- data/lib/mongo/operation/delete.rb +0 -1
- data/lib/mongo/operation/distinct.rb +1 -2
- data/lib/mongo/operation/drop.rb +1 -2
- data/lib/mongo/operation/drop_database.rb +1 -2
- data/lib/mongo/operation/drop_index.rb +1 -2
- data/lib/mongo/operation/explain.rb +1 -3
- data/lib/mongo/operation/find/builder.rb +0 -1
- data/lib/mongo/operation/find.rb +1 -3
- data/lib/mongo/operation/get_more.rb +1 -3
- data/lib/mongo/operation/indexes.rb +1 -17
- data/lib/mongo/operation/insert.rb +0 -1
- data/lib/mongo/operation/kill_cursors.rb +1 -2
- data/lib/mongo/operation/list_collections.rb +1 -2
- data/lib/mongo/operation/map_reduce.rb +1 -2
- data/lib/mongo/operation/parallel_scan.rb +1 -2
- data/lib/mongo/operation/remove_user.rb +1 -2
- data/lib/mongo/operation/shared/{polymorphic_operation.rb → op_msg_executable.rb} +11 -6
- data/lib/mongo/operation/update.rb +0 -1
- data/lib/mongo/operation/update_user.rb +1 -2
- data/lib/mongo/operation/users_info.rb +1 -2
- data/lib/mongo/operation/write_command.rb +1 -2
- data/lib/mongo/operation.rb +1 -3
- data/lib/mongo/protocol/bit_vector.rb +3 -1
- data/lib/mongo/protocol/caching_hash.rb +3 -20
- data/lib/mongo/protocol/message.rb +4 -8
- data/lib/mongo/protocol/msg.rb +1 -0
- data/lib/mongo/protocol/serializers.rb +24 -17
- data/lib/mongo/protocol.rb +0 -3
- data/lib/mongo/query_cache.rb +20 -20
- data/lib/mongo/server/app_metadata/environment.rb +255 -0
- data/lib/mongo/server/app_metadata/truncator.rb +142 -0
- data/lib/mongo/server/app_metadata.rb +29 -42
- data/lib/mongo/session.rb +1 -1
- data/lib/mongo/version.rb +1 -1
- data/spec/integration/command_spec.rb +1 -23
- data/spec/integration/connection/faas_env_spec.rb +63 -0
- data/spec/integration/find_options_spec.rb +227 -0
- data/spec/integration/ocsp_verifier_spec.rb +1 -1
- data/spec/lite_spec_helper.rb +9 -0
- data/spec/mongo/address_spec.rb +1 -1
- data/spec/mongo/client_construction_spec.rb +7 -7
- data/spec/mongo/client_spec.rb +1 -9
- data/spec/mongo/cluster_spec.rb +2 -2
- data/spec/mongo/collection_crud_spec.rb +56 -0
- data/spec/mongo/collection_spec.rb +11 -1
- data/spec/mongo/crypt/kms_spec.rb +12 -9
- data/spec/mongo/crypt_spec.rb +21 -0
- data/spec/mongo/index/view_spec.rb +1 -0
- data/spec/mongo/protocol/caching_hash_spec.rb +0 -45
- data/spec/mongo/protocol/msg_spec.rb +2 -4
- data/spec/mongo/server/app_metadata/environment_spec.rb +193 -0
- data/spec/mongo/server/app_metadata/truncator_spec.rb +158 -0
- data/spec/mongo/server/app_metadata_spec.rb +33 -47
- data/spec/mongo/socket/ssl_spec.rb +2 -8
- data/spec/runners/crud/requirement.rb +2 -2
- data/spec/shared/lib/mrss/docker_runner.rb +4 -0
- data/spec/shared/lib/mrss/lite_constraints.rb +8 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
- data/spec/shared/share/Dockerfile.erb +24 -19
- data/spec/shared/shlib/server.sh +31 -7
- data/spec/shared/shlib/set_env.sh +4 -4
- data/spec/solo/clean_exit_spec.rb +3 -10
- data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +15 -6
- data/spec/spec_tests/data/command_monitoring_unified/redacted-commands.yml +8 -0
- data/spec/support/aws_utils.rb +3 -3
- data/spec/support/certificates/atlas-ocsp-ca.crt +67 -67
- data/spec/support/certificates/atlas-ocsp.crt +103 -103
- data/spec/support/shared/app_metadata.rb +14 -2
- data.tar.gz.sig +0 -0
- metadata +1203 -1239
- metadata.gz.sig +0 -0
- data/lib/mongo/operation/aggregate/command.rb +0 -55
- data/lib/mongo/operation/collections_info/command.rb +0 -48
- data/lib/mongo/operation/command/command.rb +0 -41
- data/lib/mongo/operation/count/command.rb +0 -47
- data/lib/mongo/operation/create/command.rb +0 -47
- data/lib/mongo/operation/create_index/command.rb +0 -61
- data/lib/mongo/operation/create_user/command.rb +0 -46
- data/lib/mongo/operation/delete/command.rb +0 -52
- data/lib/mongo/operation/distinct/command.rb +0 -47
- data/lib/mongo/operation/drop/command.rb +0 -41
- data/lib/mongo/operation/drop_database/command.rb +0 -41
- data/lib/mongo/operation/drop_index/command.rb +0 -45
- data/lib/mongo/operation/explain/command.rb +0 -58
- data/lib/mongo/operation/explain/legacy.rb +0 -52
- data/lib/mongo/operation/find/builder/legacy.rb +0 -123
- data/lib/mongo/operation/find/command.rb +0 -51
- data/lib/mongo/operation/find/legacy/result.rb +0 -46
- data/lib/mongo/operation/find/legacy.rb +0 -52
- data/lib/mongo/operation/get_more/command.rb +0 -43
- data/lib/mongo/operation/get_more/legacy.rb +0 -39
- data/lib/mongo/operation/indexes/command.rb +0 -42
- data/lib/mongo/operation/indexes/legacy.rb +0 -48
- data/lib/mongo/operation/insert/command.rb +0 -55
- data/lib/mongo/operation/kill_cursors/command.rb +0 -48
- data/lib/mongo/operation/list_collections/command.rb +0 -46
- data/lib/mongo/operation/map_reduce/command.rb +0 -51
- data/lib/mongo/operation/parallel_scan/command.rb +0 -57
- data/lib/mongo/operation/remove_user/command.rb +0 -46
- data/lib/mongo/operation/shared/op_msg_or_command.rb +0 -41
- data/lib/mongo/operation/shared/op_msg_or_find_command.rb +0 -44
- data/lib/mongo/operation/update/command.rb +0 -53
- data/lib/mongo/operation/update_user/command.rb +0 -45
- data/lib/mongo/operation/users_info/command.rb +0 -46
- data/lib/mongo/operation/write_command/command.rb +0 -51
- data/lib/mongo/protocol/delete.rb +0 -172
- data/lib/mongo/protocol/insert.rb +0 -181
- data/lib/mongo/protocol/update.rb +0 -214
- data/spec/mongo/operation/delete/command_spec.rb +0 -115
- data/spec/mongo/operation/find/legacy_spec.rb +0 -131
- data/spec/mongo/operation/get_more_spec.rb +0 -63
- data/spec/mongo/operation/insert/command_spec.rb +0 -118
- data/spec/mongo/operation/update/command_spec.rb +0 -122
- data/spec/mongo/protocol/delete_spec.rb +0 -185
- data/spec/mongo/protocol/insert_spec.rb +0 -179
- data/spec/mongo/protocol/update_spec.rb +0 -204
|
@@ -51,9 +51,11 @@ module Mongo
|
|
|
51
51
|
#
|
|
52
52
|
# @param buffer [ String ] Buffer to receive the serialized value.
|
|
53
53
|
# @param value [ String ] Header value to be serialized.
|
|
54
|
+
# @param [ true, false ] validating_keys Whether keys should be validated when serializing.
|
|
55
|
+
# This option is deprecated and will not be used. It will removed in version 3.0.
|
|
54
56
|
#
|
|
55
57
|
# @return [ String ] Buffer with serialized value.
|
|
56
|
-
def self.serialize(buffer, value, validating_keys =
|
|
58
|
+
def self.serialize(buffer, value, validating_keys = nil)
|
|
57
59
|
buffer.put_bytes(value.pack(HEADER_PACK))
|
|
58
60
|
end
|
|
59
61
|
|
|
@@ -80,7 +82,7 @@ module Mongo
|
|
|
80
82
|
# @param value [ String ] The string to be serialized.
|
|
81
83
|
#
|
|
82
84
|
# @return [ String ] Buffer with serialized value.
|
|
83
|
-
def self.serialize(buffer, value, validating_keys =
|
|
85
|
+
def self.serialize(buffer, value, validating_keys = nil)
|
|
84
86
|
buffer.put_cstring(value)
|
|
85
87
|
end
|
|
86
88
|
end
|
|
@@ -96,7 +98,7 @@ module Mongo
|
|
|
96
98
|
# @param value [ Fixnum ] Ignored value.
|
|
97
99
|
#
|
|
98
100
|
# @return [ String ] Buffer with serialized value.
|
|
99
|
-
def self.serialize(buffer, value, validating_keys =
|
|
101
|
+
def self.serialize(buffer, value, validating_keys = nil)
|
|
100
102
|
buffer.put_int32(ZERO)
|
|
101
103
|
end
|
|
102
104
|
end
|
|
@@ -112,7 +114,7 @@ module Mongo
|
|
|
112
114
|
# @param value [ Integer | BSON::Int32 ] 32-bit integer to be serialized.
|
|
113
115
|
#
|
|
114
116
|
# @return [String] Buffer with serialized value.
|
|
115
|
-
def self.serialize(buffer, value, validating_keys =
|
|
117
|
+
def self.serialize(buffer, value, validating_keys = nil)
|
|
116
118
|
if value.is_a?(BSON::Int32)
|
|
117
119
|
if value.respond_to?(:value)
|
|
118
120
|
# bson-ruby >= 4.6.0
|
|
@@ -146,7 +148,7 @@ module Mongo
|
|
|
146
148
|
# @param value [ Integer | BSON::Int64 ] 64-bit integer to be serialized.
|
|
147
149
|
#
|
|
148
150
|
# @return [ String ] Buffer with serialized value.
|
|
149
|
-
def self.serialize(buffer, value, validating_keys =
|
|
151
|
+
def self.serialize(buffer, value, validating_keys = nil)
|
|
150
152
|
if value.is_a?(BSON::Int64)
|
|
151
153
|
if value.respond_to?(:value)
|
|
152
154
|
# bson-ruby >= 4.6.0
|
|
@@ -182,19 +184,20 @@ module Mongo
|
|
|
182
184
|
# @param [ Array<Hash, BSON::Document> ] value The sections to be serialized.
|
|
183
185
|
# @param [ Fixnum ] max_bson_size The max bson size of documents in the sections.
|
|
184
186
|
# @param [ true, false ] validating_keys Whether to validate document keys.
|
|
187
|
+
# This option is deprecated and will not be used. It will removed in version 3.0.
|
|
185
188
|
#
|
|
186
189
|
# @return [ BSON::ByteBuffer ] Buffer with serialized value.
|
|
187
190
|
#
|
|
188
191
|
# @since 2.5.0
|
|
189
|
-
def self.serialize(buffer, value, max_bson_size = nil, validating_keys =
|
|
192
|
+
def self.serialize(buffer, value, max_bson_size = nil, validating_keys = nil)
|
|
190
193
|
value.each do |section|
|
|
191
194
|
case section[:type]
|
|
192
195
|
when PayloadZero::TYPE
|
|
193
|
-
PayloadZero.serialize(buffer, section[:payload], max_bson_size
|
|
196
|
+
PayloadZero.serialize(buffer, section[:payload], max_bson_size)
|
|
194
197
|
when nil
|
|
195
|
-
PayloadZero.serialize(buffer, section[:payload], max_bson_size
|
|
198
|
+
PayloadZero.serialize(buffer, section[:payload], max_bson_size)
|
|
196
199
|
when PayloadOne::TYPE
|
|
197
|
-
PayloadOne.serialize(buffer, section[:payload], max_bson_size
|
|
200
|
+
PayloadOne.serialize(buffer, section[:payload], max_bson_size)
|
|
198
201
|
else
|
|
199
202
|
raise Error::UnknownPayloadType.new(section[:type])
|
|
200
203
|
end
|
|
@@ -259,13 +262,14 @@ module Mongo
|
|
|
259
262
|
# @param [ BSON::Document, Hash ] value The object to serialize.
|
|
260
263
|
# @param [ Fixnum ] max_bson_size The max bson size of documents in the section.
|
|
261
264
|
# @param [ true, false ] validating_keys Whether to validate document keys.
|
|
265
|
+
# This option is deprecated and will not be used. It will removed in version 3.0.
|
|
262
266
|
#
|
|
263
267
|
# @return [ BSON::ByteBuffer ] Buffer with serialized value.
|
|
264
268
|
#
|
|
265
269
|
# @since 2.5.0
|
|
266
|
-
def self.serialize(buffer, value, max_bson_size = nil, validating_keys =
|
|
270
|
+
def self.serialize(buffer, value, max_bson_size = nil, validating_keys = nil)
|
|
267
271
|
buffer.put_byte(TYPE_BYTE)
|
|
268
|
-
Serializers::Document.serialize(buffer, value, max_bson_size
|
|
272
|
+
Serializers::Document.serialize(buffer, value, max_bson_size)
|
|
269
273
|
end
|
|
270
274
|
|
|
271
275
|
# Deserializes a section of payload type 0 of an OP_MSG from the IO stream.
|
|
@@ -307,17 +311,18 @@ module Mongo
|
|
|
307
311
|
# @param [ BSON::Document, Hash ] value The object to serialize.
|
|
308
312
|
# @param [ Fixnum ] max_bson_size The max bson size of documents in the section.
|
|
309
313
|
# @param [ true, false ] validating_keys Whether to validate document keys.
|
|
314
|
+
# This option is deprecated and will not be used. It will removed in version 3.0.
|
|
310
315
|
#
|
|
311
316
|
# @return [ BSON::ByteBuffer ] Buffer with serialized value.
|
|
312
317
|
#
|
|
313
318
|
# @since 2.5.0
|
|
314
|
-
def self.serialize(buffer, value, max_bson_size = nil, validating_keys =
|
|
319
|
+
def self.serialize(buffer, value, max_bson_size = nil, validating_keys = nil)
|
|
315
320
|
buffer.put_byte(TYPE_BYTE)
|
|
316
321
|
start = buffer.length
|
|
317
322
|
buffer.put_int32(0) # hold for size
|
|
318
323
|
buffer.put_cstring(value[:identifier])
|
|
319
324
|
value[:sequence].each do |document|
|
|
320
|
-
Document.serialize(buffer, document, max_bson_size
|
|
325
|
+
Document.serialize(buffer, document, max_bson_size)
|
|
321
326
|
end
|
|
322
327
|
buffer.replace_int32(start, buffer.length - start)
|
|
323
328
|
end
|
|
@@ -356,9 +361,9 @@ module Mongo
|
|
|
356
361
|
# @param value [ Hash ] Document to serialize as BSON.
|
|
357
362
|
#
|
|
358
363
|
# @return [ String ] Buffer with serialized value.
|
|
359
|
-
def self.serialize(buffer, value, max_bson_size = nil, validating_keys =
|
|
364
|
+
def self.serialize(buffer, value, max_bson_size = nil, validating_keys = nil)
|
|
360
365
|
start_size = buffer.length
|
|
361
|
-
value.to_bson(buffer
|
|
366
|
+
value.to_bson(buffer)
|
|
362
367
|
serialized_size = buffer.length - start_size
|
|
363
368
|
if max_bson_size && serialized_size > max_bson_size
|
|
364
369
|
raise Error::MaxBSONSize,
|
|
@@ -401,11 +406,12 @@ module Mongo
|
|
|
401
406
|
# @param [ BSON::ByteBuffer ] buffer Buffer to receive the single byte.
|
|
402
407
|
# @param [ String ] value The byte to write to the buffer.
|
|
403
408
|
# @param [ true, false ] validating_keys Whether to validate keys.
|
|
409
|
+
# This option is deprecated and will not be used. It will removed in version 3.0.
|
|
404
410
|
#
|
|
405
411
|
# @return [ BSON::ByteBuffer ] Buffer with serialized value.
|
|
406
412
|
#
|
|
407
413
|
# @since 2.5.0
|
|
408
|
-
def self.serialize(buffer, value, validating_keys =
|
|
414
|
+
def self.serialize(buffer, value, validating_keys = nil)
|
|
409
415
|
buffer.put_byte(value)
|
|
410
416
|
end
|
|
411
417
|
|
|
@@ -432,11 +438,12 @@ module Mongo
|
|
|
432
438
|
# @param [ BSON::ByteBuffer ] buffer Buffer to receive the bytes.
|
|
433
439
|
# @param [ String ] value The bytes to write to the buffer.
|
|
434
440
|
# @param [ true, false ] validating_keys Whether to validate keys.
|
|
441
|
+
# This option is deprecated and will not be used. It will removed in version 3.0.
|
|
435
442
|
#
|
|
436
443
|
# @return [ BSON::ByteBuffer ] Buffer with serialized value.
|
|
437
444
|
#
|
|
438
445
|
# @since 2.5.0
|
|
439
|
-
def self.serialize(buffer, value, validating_keys =
|
|
446
|
+
def self.serialize(buffer, value, validating_keys = nil)
|
|
440
447
|
buffer.put_bytes(value)
|
|
441
448
|
end
|
|
442
449
|
|
data/lib/mongo/protocol.rb
CHANGED
|
@@ -10,12 +10,9 @@ require 'mongo/protocol/caching_hash'
|
|
|
10
10
|
|
|
11
11
|
# Client Requests
|
|
12
12
|
require 'mongo/protocol/compressed'
|
|
13
|
-
require 'mongo/protocol/delete'
|
|
14
13
|
require 'mongo/protocol/get_more'
|
|
15
|
-
require 'mongo/protocol/insert'
|
|
16
14
|
require 'mongo/protocol/kill_cursors'
|
|
17
15
|
require 'mongo/protocol/query'
|
|
18
|
-
require 'mongo/protocol/update'
|
|
19
16
|
require 'mongo/protocol/msg'
|
|
20
17
|
|
|
21
18
|
# Server Responses
|
data/lib/mongo/query_cache.rb
CHANGED
|
@@ -114,24 +114,24 @@ module Mongo
|
|
|
114
114
|
#
|
|
115
115
|
# @param [ Mongo::CachingCursor ] cursor The CachingCursor instance to store.
|
|
116
116
|
#
|
|
117
|
-
# @option opts [ String | nil ] namespace The namespace of the query,
|
|
117
|
+
# @option opts [ String | nil ] :namespace The namespace of the query,
|
|
118
118
|
# in the format "database_name.collection_name".
|
|
119
|
-
# @option opts [ Array, Hash ] selector The selector passed to the query.
|
|
119
|
+
# @option opts [ Array, Hash ] :selector The selector passed to the query.
|
|
120
120
|
# For most queries, this will be a Hash, but for aggregations, this
|
|
121
121
|
# will be an Array representing the aggregation pipeline. May not be nil.
|
|
122
|
-
# @option opts [ Integer | nil ] skip The skip value of the query.
|
|
123
|
-
# @option opts [ Hash | nil ] sort The order of the query results
|
|
122
|
+
# @option opts [ Integer | nil ] :skip The skip value of the query.
|
|
123
|
+
# @option opts [ Hash | nil ] :sort The order of the query results
|
|
124
124
|
# (e.g. { name: -1 }).
|
|
125
|
-
# @option opts [ Integer | nil ] limit The limit value of the query.
|
|
126
|
-
# @option opts [ Hash | nil ] projection The projection of the query
|
|
125
|
+
# @option opts [ Integer | nil ] :limit The limit value of the query.
|
|
126
|
+
# @option opts [ Hash | nil ] :projection The projection of the query
|
|
127
127
|
# results (e.g. { name: 1 }).
|
|
128
|
-
# @option opts [ Hash | nil ] collation The collation of the query
|
|
128
|
+
# @option opts [ Hash | nil ] :collation The collation of the query
|
|
129
129
|
# (e.g. { "locale" => "fr_CA" }).
|
|
130
|
-
# @option opts [ Hash | nil ] read_concern The read concern of the query
|
|
130
|
+
# @option opts [ Hash | nil ] :read_concern The read concern of the query
|
|
131
131
|
# (e.g. { level: :majority }).
|
|
132
|
-
# @option opts [ Hash | nil ] read_preference The read preference of
|
|
132
|
+
# @option opts [ Hash | nil ] :read_preference The read preference of
|
|
133
133
|
# the query (e.g. { mode: :secondary }).
|
|
134
|
-
# @option opts [ Boolean | nil ] multi_collection Whether the query
|
|
134
|
+
# @option opts [ Boolean | nil ] :multi_collection Whether the query
|
|
135
135
|
# results could potentially come from multiple collections. When true,
|
|
136
136
|
# these results will be stored under the nil namespace key and cleared
|
|
137
137
|
# on every write command.
|
|
@@ -152,24 +152,24 @@ module Mongo
|
|
|
152
152
|
# For the given query options, retrieve a cached cursor that can be used
|
|
153
153
|
# to obtain the correct query results, if one exists in the cache.
|
|
154
154
|
#
|
|
155
|
-
# @option opts [ String | nil ] namespace The namespace of the query,
|
|
155
|
+
# @option opts [ String | nil ] :namespace The namespace of the query,
|
|
156
156
|
# in the format "database_name.collection_name".
|
|
157
|
-
# @option opts [ Array, Hash ] selector The selector passed to the query.
|
|
157
|
+
# @option opts [ Array, Hash ] :selector The selector passed to the query.
|
|
158
158
|
# For most queries, this will be a Hash, but for aggregations, this
|
|
159
159
|
# will be an Array representing the aggregation pipeline. May not be nil.
|
|
160
|
-
# @option opts [ Integer | nil ] skip The skip value of the query.
|
|
161
|
-
# @option opts [ Hash | nil ] sort The order of the query results
|
|
160
|
+
# @option opts [ Integer | nil ] :skip The skip value of the query.
|
|
161
|
+
# @option opts [ Hash | nil ] :sort The order of the query results
|
|
162
162
|
# (e.g. { name: -1 }).
|
|
163
|
-
# @option opts [ Integer | nil ] limit The limit value of the query.
|
|
164
|
-
# @option opts [ Hash | nil ] projection The projection of the query
|
|
163
|
+
# @option opts [ Integer | nil ] :limit The limit value of the query.
|
|
164
|
+
# @option opts [ Hash | nil ] :projection The projection of the query
|
|
165
165
|
# results (e.g. { name: 1 }).
|
|
166
|
-
# @option opts [ Hash | nil ] collation The collation of the query
|
|
166
|
+
# @option opts [ Hash | nil ] :collation The collation of the query
|
|
167
167
|
# (e.g. { "locale" => "fr_CA" }).
|
|
168
|
-
# @option opts [ Hash | nil ] read_concern The read concern of the query
|
|
168
|
+
# @option opts [ Hash | nil ] :read_concern The read concern of the query
|
|
169
169
|
# (e.g. { level: :majority }).
|
|
170
|
-
# @option opts [ Hash | nil ] read_preference The read preference of
|
|
170
|
+
# @option opts [ Hash | nil ] :read_preference The read preference of
|
|
171
171
|
# the query (e.g. { mode: :secondary }).
|
|
172
|
-
# @option opts [ Boolean | nil ] multi_collection Whether the query
|
|
172
|
+
# @option opts [ Boolean | nil ] :multi_collection Whether the query
|
|
173
173
|
# results could potentially come from multiple collections. When true,
|
|
174
174
|
# these results will be stored under the nil namespace key and cleared
|
|
175
175
|
# on every write command.
|
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2016-2023 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
|
+
class Server
|
|
19
|
+
class AppMetadata
|
|
20
|
+
# Implements the logic from the handshake spec, for deducing and
|
|
21
|
+
# reporting the current FaaS environment in which the program is
|
|
22
|
+
# executing.
|
|
23
|
+
#
|
|
24
|
+
# @api private
|
|
25
|
+
class Environment
|
|
26
|
+
# Error class for reporting that too many discriminators were found
|
|
27
|
+
# in the environment. (E.g. if the environment reports that it is
|
|
28
|
+
# running under both AWS and Azure.)
|
|
29
|
+
class TooManyEnvironments < Mongo::Error; end
|
|
30
|
+
|
|
31
|
+
# Error class for reporting that a required environment variable is
|
|
32
|
+
# missing.
|
|
33
|
+
class MissingVariable < Mongo::Error; end
|
|
34
|
+
|
|
35
|
+
# Error class for reporting that the wrong type was given for a
|
|
36
|
+
# field.
|
|
37
|
+
class TypeMismatch < Mongo::Error; end
|
|
38
|
+
|
|
39
|
+
# Error class for reporting that the value for a field is too long.
|
|
40
|
+
class ValueTooLong < Mongo::Error; end
|
|
41
|
+
|
|
42
|
+
# This value is not explicitly specified in the spec, only implied to be
|
|
43
|
+
# less than 512.
|
|
44
|
+
MAXIMUM_VALUE_LENGTH = 500
|
|
45
|
+
|
|
46
|
+
# The mapping that determines which FaaS environment is active, based
|
|
47
|
+
# on which environment variable(s) are present.
|
|
48
|
+
DISCRIMINATORS = {
|
|
49
|
+
'AWS_EXECUTION_ENV' => { pattern: /^AWS_Lambda_/, name: 'aws.lambda' },
|
|
50
|
+
'AWS_LAMBDA_RUNTIME_API' => { name: 'aws.lambda' },
|
|
51
|
+
'FUNCTIONS_WORKER_RUNTIME' => { name: 'azure.func' },
|
|
52
|
+
'K_SERVICE' => { name: 'gcp.func' },
|
|
53
|
+
'FUNCTION_NAME' => { name: 'gcp.func' },
|
|
54
|
+
'VERCEL' => { name: 'vercel' },
|
|
55
|
+
}.freeze
|
|
56
|
+
|
|
57
|
+
# Describes how to coerce values of the specified type.
|
|
58
|
+
COERCIONS = {
|
|
59
|
+
string: ->(v) { String(v) },
|
|
60
|
+
integer: ->(v) { Integer(v) }
|
|
61
|
+
}.freeze
|
|
62
|
+
|
|
63
|
+
# Describes which fields are required for each FaaS environment,
|
|
64
|
+
# along with their expected types, and how they should be named in
|
|
65
|
+
# the handshake document.
|
|
66
|
+
FIELDS = {
|
|
67
|
+
'aws.lambda' => {
|
|
68
|
+
'AWS_REGION' => { field: :region, type: :string },
|
|
69
|
+
'AWS_LAMBDA_FUNCTION_MEMORY_SIZE' => { field: :memory_mb, type: :integer },
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
'azure.func' => {},
|
|
73
|
+
|
|
74
|
+
'gcp.func' => {
|
|
75
|
+
'FUNCTION_MEMORY_MB' => { field: :memory_mb, type: :integer },
|
|
76
|
+
'FUNCTION_TIMEOUT_SEC' => { field: :timeout_sec, type: :integer },
|
|
77
|
+
'FUNCTION_REGION' => { field: :region, type: :string },
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
'vercel' => {
|
|
81
|
+
'VERCEL_URL' => { field: :url, type: :string },
|
|
82
|
+
'VERCEL_REGION' => { field: :region, type: :string },
|
|
83
|
+
},
|
|
84
|
+
}.freeze
|
|
85
|
+
|
|
86
|
+
# @return [ String | nil ] the name of the FaaS environment that was
|
|
87
|
+
# detected, or nil if no valid FaaS environment was detected.
|
|
88
|
+
attr_reader :name
|
|
89
|
+
|
|
90
|
+
# @return [ Hash | nil ] the fields describing the detected FaaS
|
|
91
|
+
# environment.
|
|
92
|
+
attr_reader :fields
|
|
93
|
+
|
|
94
|
+
# @return [ String | nil ] the error message explaining why a valid
|
|
95
|
+
# FaaS environment was not detected, or nil if no error occurred.
|
|
96
|
+
#
|
|
97
|
+
# @note These error messagess are not to be propogated to the
|
|
98
|
+
# user; they are intended only for troubleshooting and debugging.)
|
|
99
|
+
attr_reader :error
|
|
100
|
+
|
|
101
|
+
# Create a new AppMetadata::Environment object, initializing it from
|
|
102
|
+
# the current ENV variables. If no FaaS environment is detected, or
|
|
103
|
+
# if the environment contains invalid or contradictory state, it will
|
|
104
|
+
# be initialized with {{name}} set to {{nil}}.
|
|
105
|
+
def initialize
|
|
106
|
+
@error = nil
|
|
107
|
+
@name = detect_environment
|
|
108
|
+
populate_fields
|
|
109
|
+
rescue TooManyEnvironments => e
|
|
110
|
+
self.error = "too many environments detected: #{e.message}"
|
|
111
|
+
rescue MissingVariable => e
|
|
112
|
+
self.error = "missing environment variable: #{e.message}"
|
|
113
|
+
rescue TypeMismatch => e
|
|
114
|
+
self.error = e.message
|
|
115
|
+
rescue ValueTooLong => e
|
|
116
|
+
self.error = "value for #{e.message} is too long"
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Queries whether the current environment is a valid FaaS environment.
|
|
120
|
+
#
|
|
121
|
+
# @return [ true | false ] whether the environment is a FaaS
|
|
122
|
+
# environment or not.
|
|
123
|
+
def faas?
|
|
124
|
+
@name != nil
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Queries whether the current environment is a valid AWS Lambda
|
|
128
|
+
# environment.
|
|
129
|
+
#
|
|
130
|
+
# @return [ true | false ] whether the environment is a AWS Lambda
|
|
131
|
+
# environment or not.
|
|
132
|
+
def aws?
|
|
133
|
+
@name == 'aws.lambda'
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
# Queries whether the current environment is a valid Azure
|
|
137
|
+
# environment.
|
|
138
|
+
#
|
|
139
|
+
# @return [ true | false ] whether the environment is a Azure
|
|
140
|
+
# environment or not.
|
|
141
|
+
def azure?
|
|
142
|
+
@name == 'azure.func'
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# Queries whether the current environment is a valid GCP
|
|
146
|
+
# environment.
|
|
147
|
+
#
|
|
148
|
+
# @return [ true | false ] whether the environment is a GCP
|
|
149
|
+
# environment or not.
|
|
150
|
+
def gcp?
|
|
151
|
+
@name == 'gcp.func'
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# Queries whether the current environment is a valid Vercel
|
|
155
|
+
# environment.
|
|
156
|
+
#
|
|
157
|
+
# @return [ true | false ] whether the environment is a Vercel
|
|
158
|
+
# environment or not.
|
|
159
|
+
def vercel?
|
|
160
|
+
@name == 'vercel'
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Compiles the detected environment information into a Hash. It will
|
|
164
|
+
# always include a {{name}} key, but may include other keys as well,
|
|
165
|
+
# depending on the detected FaaS environment. (See the handshake
|
|
166
|
+
# spec for details.)
|
|
167
|
+
#
|
|
168
|
+
# @return [ Hash ] the detected environment information.
|
|
169
|
+
def to_h
|
|
170
|
+
fields.merge(name: name)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
private
|
|
174
|
+
|
|
175
|
+
# Searches the DESCRIMINATORS list to see which (if any) apply to
|
|
176
|
+
# the current environment.
|
|
177
|
+
#
|
|
178
|
+
# @return [ String | nil ] the name of the detected FaaS provider.
|
|
179
|
+
#
|
|
180
|
+
# @raise [ TooManyEnvironments ] if the environment contains
|
|
181
|
+
# discriminating variables for more than one FaaS provider.
|
|
182
|
+
def detect_environment
|
|
183
|
+
matches = DISCRIMINATORS.keys.select { |k| discriminator_matches?(k) }
|
|
184
|
+
names = matches.map { |m| DISCRIMINATORS[m][:name] }.uniq
|
|
185
|
+
|
|
186
|
+
raise TooManyEnvironments, names.join(', ') if names.length > 1
|
|
187
|
+
|
|
188
|
+
names.first
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# Determines whether the named environment variable exists, and (if
|
|
192
|
+
# a pattern has been declared for that descriminator) whether the
|
|
193
|
+
# pattern matches the value of the variable.
|
|
194
|
+
#
|
|
195
|
+
# @param [ String ] var the name of the environment variable
|
|
196
|
+
#
|
|
197
|
+
# @return [ true | false ] if the variable describes the current
|
|
198
|
+
# environment or not.
|
|
199
|
+
def discriminator_matches?(var)
|
|
200
|
+
return false unless ENV[var]
|
|
201
|
+
|
|
202
|
+
disc = DISCRIMINATORS[var]
|
|
203
|
+
return true unless disc[:pattern]
|
|
204
|
+
|
|
205
|
+
disc[:pattern].match?(ENV[var])
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Extracts environment information from the current environment
|
|
209
|
+
# variables, based on the detected FaaS environment. Populates the
|
|
210
|
+
# {{@fields}} instance variable.
|
|
211
|
+
def populate_fields
|
|
212
|
+
return unless name
|
|
213
|
+
|
|
214
|
+
@fields = FIELDS[name].each_with_object({}) do |(var, defn), fields|
|
|
215
|
+
fields[defn[:field]] = extract_field(var, defn)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# Extracts the named variable from the environment and validates it
|
|
220
|
+
# against its declared definition.
|
|
221
|
+
#
|
|
222
|
+
# @param [ String ] var The name of the environment variable to look
|
|
223
|
+
# for.
|
|
224
|
+
# @param [ Hash ] definition The definition of the field that applies
|
|
225
|
+
# to the named variable.
|
|
226
|
+
#
|
|
227
|
+
# @return [ Integer | String ] the validated and coerced value of the
|
|
228
|
+
# given environment variable.
|
|
229
|
+
#
|
|
230
|
+
# @raise [ MissingVariable ] if the environment does not include a
|
|
231
|
+
# variable required by the current FaaS provider.
|
|
232
|
+
# @raise [ ValueTooLong ] if a required variable is too long.
|
|
233
|
+
# @raise [ TypeMismatch ] if a required variable cannot be coerced to
|
|
234
|
+
# the expected type.
|
|
235
|
+
def extract_field(var, definition)
|
|
236
|
+
raise MissingVariable, var unless ENV[var]
|
|
237
|
+
raise ValueTooLong, var if ENV[var].length > MAXIMUM_VALUE_LENGTH
|
|
238
|
+
|
|
239
|
+
COERCIONS[definition[:type]].call(ENV[var])
|
|
240
|
+
rescue ArgumentError
|
|
241
|
+
raise TypeMismatch,
|
|
242
|
+
"#{var} must be #{definition[:type]} (got #{ENV[var].inspect})"
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# Sets the error message to the given value and sets the name to nil.
|
|
246
|
+
#
|
|
247
|
+
# @param [ String ] msg The error message to store.
|
|
248
|
+
def error=(msg)
|
|
249
|
+
@name = nil
|
|
250
|
+
@error = msg
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
end
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# Copyright (C) 2016-2023 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
|
+
class Server
|
|
19
|
+
class AppMetadata
|
|
20
|
+
# Implements the metadata truncation logic described in the handshake
|
|
21
|
+
# spec.
|
|
22
|
+
#
|
|
23
|
+
# @api private
|
|
24
|
+
class Truncator
|
|
25
|
+
# @return [ BSON::Document ] the document being truncated.
|
|
26
|
+
attr_reader :document
|
|
27
|
+
|
|
28
|
+
# The max application metadata document byte size.
|
|
29
|
+
MAX_DOCUMENT_SIZE = 512
|
|
30
|
+
|
|
31
|
+
# Creates a new Truncator instance and tries enforcing the maximum
|
|
32
|
+
# document size on the given document.
|
|
33
|
+
#
|
|
34
|
+
# @param [ BSON::Document] document The document to (potentially)
|
|
35
|
+
# truncate.
|
|
36
|
+
#
|
|
37
|
+
# @note The document is modified in-place; if you wish to keep the
|
|
38
|
+
# original unchanged, you must deep-clone it prior to sending it to
|
|
39
|
+
# a truncator.
|
|
40
|
+
def initialize(document)
|
|
41
|
+
@document = document
|
|
42
|
+
try_truncate!
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# The current size of the document, in bytes, as a serialized BSON
|
|
46
|
+
# document.
|
|
47
|
+
#
|
|
48
|
+
# @return [ Integer ] the size of the document
|
|
49
|
+
def size
|
|
50
|
+
@document.to_bson.to_s.length
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Whether the document fits within the required maximum document size.
|
|
54
|
+
#
|
|
55
|
+
# @return [ true | false ] if the document is okay or not.
|
|
56
|
+
def ok?
|
|
57
|
+
size <= MAX_DOCUMENT_SIZE
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
|
|
62
|
+
# How many extra bytes must be trimmed before the document may be
|
|
63
|
+
# considered #ok?.
|
|
64
|
+
#
|
|
65
|
+
# @return [ Integer ] how many bytes larger the document is than the
|
|
66
|
+
# maximum document size.
|
|
67
|
+
def excess
|
|
68
|
+
size - MAX_DOCUMENT_SIZE
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Attempt to truncate the document using the documented metadata
|
|
72
|
+
# priorities (see the handshake specification).
|
|
73
|
+
def try_truncate!
|
|
74
|
+
%i[ env_fields os_fields env platform ].each do |target|
|
|
75
|
+
break if ok?
|
|
76
|
+
|
|
77
|
+
send(:"try_truncate_#{target}!")
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Attempt to truncate or remove the {{:platform}} key from the
|
|
82
|
+
# document.
|
|
83
|
+
def try_truncate_platform!
|
|
84
|
+
@document.delete(:platform) unless try_truncate_string(@document[:platform])
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Attempt to truncate the keys in the {{:env}} subdocument.
|
|
88
|
+
def try_truncate_env_fields!
|
|
89
|
+
try_truncate_hash(@document[:env], reserved: %w[ name ])
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Attempt to truncate the keys in the {{:os}} subdocument.
|
|
93
|
+
def try_truncate_os_fields!
|
|
94
|
+
try_truncate_hash(@document[:os], reserved: %w[ type ])
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Remove the {{:env}} key from the document.
|
|
98
|
+
def try_truncate_env!
|
|
99
|
+
@document.delete(:env)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# A helper method for truncating a string (in-place) by whatever
|
|
103
|
+
# {{#excess}} is required.
|
|
104
|
+
#
|
|
105
|
+
# @param [ String ] string the string value to truncate.
|
|
106
|
+
#
|
|
107
|
+
# @note the parameter is modified in-place.
|
|
108
|
+
def try_truncate_string(string)
|
|
109
|
+
length = string&.length || 0
|
|
110
|
+
|
|
111
|
+
return false if excess > length
|
|
112
|
+
|
|
113
|
+
string[(length - excess)..-1] = ''
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# A helper method for removing the keys of a Hash (in-place) until
|
|
117
|
+
# the document is the necessary size. The keys are considered in order
|
|
118
|
+
# (using the Hash's native key ordering), and each will be removed from
|
|
119
|
+
# the hash in turn, until the document is the necessary size.
|
|
120
|
+
#
|
|
121
|
+
# Any keys in the {{reserved}} list will be ignored.
|
|
122
|
+
#
|
|
123
|
+
# @param [ Hash | nil ] hash the Hash instance to consider.
|
|
124
|
+
# @param [ Array ] reserved the list of keys to ignore in the hash.
|
|
125
|
+
#
|
|
126
|
+
# @note the hash parameter is modified in-place.
|
|
127
|
+
def try_truncate_hash(hash, reserved: [])
|
|
128
|
+
return false unless hash
|
|
129
|
+
|
|
130
|
+
keys = hash.keys - reserved
|
|
131
|
+
keys.each do |key|
|
|
132
|
+
hash.delete(key)
|
|
133
|
+
|
|
134
|
+
return true if ok?
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
false
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
142
|
+
end
|