mongo 2.18.0.beta1 → 2.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (149) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/mongo/bulk_write.rb +8 -2
  4. data/lib/mongo/client.rb +19 -5
  5. data/lib/mongo/client_encryption.rb +86 -4
  6. data/lib/mongo/cluster.rb +6 -4
  7. data/lib/mongo/collection/view/aggregation.rb +3 -0
  8. data/lib/mongo/collection/view/change_stream.rb +9 -0
  9. data/lib/mongo/collection/view/iterable.rb +1 -0
  10. data/lib/mongo/collection/view/readable.rb +11 -3
  11. data/lib/mongo/collection.rb +9 -1
  12. data/lib/mongo/config.rb +11 -0
  13. data/lib/mongo/crypt/auto_encrypter.rb +49 -21
  14. data/lib/mongo/crypt/binding.rb +73 -48
  15. data/lib/mongo/crypt/data_key_context.rb +6 -1
  16. data/lib/mongo/crypt/encryption_io.rb +66 -0
  17. data/lib/mongo/crypt/explicit_encrypter.rb +116 -5
  18. data/lib/mongo/crypt/explicit_encryption_context.rb +3 -8
  19. data/lib/mongo/crypt/handle.rb +26 -8
  20. data/lib/mongo/crypt/kms/aws.rb +11 -3
  21. data/lib/mongo/crypt/kms/azure.rb +14 -6
  22. data/lib/mongo/crypt/kms/gcp.rb +12 -5
  23. data/lib/mongo/crypt/kms/kmip.rb +15 -9
  24. data/lib/mongo/crypt/kms/local.rb +9 -1
  25. data/lib/mongo/crypt/kms/master_key_document.rb +1 -1
  26. data/lib/mongo/crypt/rewrap_many_data_key_context.rb +46 -0
  27. data/lib/mongo/crypt/rewrap_many_data_key_result.rb +37 -0
  28. data/lib/mongo/crypt/status.rb +8 -2
  29. data/lib/mongo/crypt.rb +2 -0
  30. data/lib/mongo/database.rb +10 -27
  31. data/lib/mongo/error/missing_file_chunk.rb +8 -2
  32. data/lib/mongo/grid/stream/read.rb +6 -0
  33. data/lib/mongo/index/view.rb +1 -0
  34. data/lib/mongo/operation/create/op_msg.rb +1 -13
  35. data/lib/mongo/operation/distinct/op_msg.rb +4 -1
  36. data/lib/mongo/protocol/msg.rb +0 -16
  37. data/lib/mongo/server/connection_pool.rb +5 -4
  38. data/lib/mongo/server/monitor/connection.rb +10 -4
  39. data/lib/mongo/server/monitor.rb +4 -0
  40. data/lib/mongo/server/push_monitor.rb +4 -0
  41. data/lib/mongo/version.rb +1 -1
  42. data/lib/mongo.rb +2 -0
  43. data/spec/README.md +14 -0
  44. data/spec/integration/change_stream_spec.rb +1 -1
  45. data/spec/integration/client_construction_spec.rb +73 -7
  46. data/spec/integration/client_side_encryption/auto_encryption_command_monitoring_spec.rb +165 -164
  47. data/spec/integration/client_side_encryption/decryption_events_prose_spec.rb +158 -0
  48. data/spec/integration/client_side_encryption/explicit_queryable_encryption_spec.rb +5 -5
  49. data/spec/integration/client_side_encryption/kms_tls_options_spec.rb +50 -8
  50. data/spec/integration/client_side_encryption/unique_index_on_key_alt_names_prose_spec.rb +85 -0
  51. data/spec/integration/ocsp_verifier_spec.rb +1 -1
  52. data/spec/integration/reconnect_spec.rb +2 -0
  53. data/spec/integration/sdam_events_spec.rb +40 -0
  54. data/spec/integration/srv_monitoring_spec.rb +1 -0
  55. data/spec/integration/srv_spec.rb +1 -0
  56. data/spec/lite_spec_helper.rb +5 -4
  57. data/spec/mongo/bulk_write_spec.rb +13 -0
  58. data/spec/mongo/client_construction_spec.rb +45 -2
  59. data/spec/mongo/client_encryption_spec.rb +0 -12
  60. data/spec/mongo/client_spec.rb +1 -1
  61. data/spec/mongo/collection/view/aggregation_spec.rb +119 -0
  62. data/spec/mongo/collection/view/readable_spec.rb +630 -5
  63. data/spec/mongo/collection_spec.rb +32 -0
  64. data/spec/mongo/crypt/auto_encrypter_spec.rb +110 -0
  65. data/spec/mongo/crypt/binding/context_spec.rb +3 -35
  66. data/spec/mongo/crypt/data_key_context_spec.rb +1 -1
  67. data/spec/mongo/crypt/explicit_encryption_context_spec.rb +8 -3
  68. data/spec/mongo/crypt/handle_spec.rb +39 -3
  69. data/spec/mongo/crypt/kms/credentials_spec.rb +0 -47
  70. data/spec/mongo/index/view_spec.rb +56 -0
  71. data/spec/mongo/operation/create/op_msg_spec.rb +0 -42
  72. data/spec/mongo/server/connection_pool_spec.rb +26 -4
  73. data/spec/mongo/socket/ssl_spec.rb +3 -3
  74. data/spec/runners/crud/requirement.rb +6 -1
  75. data/spec/runners/crud/test.rb +1 -1
  76. data/spec/runners/transactions/spec.rb +2 -2
  77. data/spec/runners/transactions/test.rb +4 -20
  78. data/spec/runners/transactions.rb +2 -2
  79. data/spec/runners/unified/assertions.rb +32 -2
  80. data/spec/runners/unified/change_stream_operations.rb +3 -0
  81. data/spec/runners/unified/client_side_encryption_operations.rb +83 -0
  82. data/spec/runners/unified/crud_operations.rb +17 -2
  83. data/spec/runners/unified/ddl_operations.rb +27 -2
  84. data/spec/runners/unified/grid_fs_operations.rb +21 -0
  85. data/spec/runners/unified/test.rb +59 -1
  86. data/spec/shared/lib/mrss/docker_runner.rb +2 -0
  87. data/spec/shared/lib/mrss/eg_config_utils.rb +51 -0
  88. data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
  89. data/spec/shared/shlib/set_env.sh +3 -0
  90. data/spec/solo/clean_exit_spec.rb +5 -0
  91. data/spec/spec_tests/client_side_encryption_spec.rb +1 -1
  92. data/spec/spec_tests/client_side_encryption_unified_spec.rb +16 -0
  93. data/spec/spec_tests/data/change_streams_unified/change-streams-showExpandedEvents.yml +298 -0
  94. data/spec/spec_tests/data/client_side_encryption/create-and-createIndexes.yml +58 -0
  95. data/spec/spec_tests/data/client_side_encryption/fle2-Delete.yml +1 -1
  96. data/spec/spec_tests/data/client_side_encryption/fle2-EncryptedFields-vs-jsonSchema.yml +1 -1
  97. data/spec/spec_tests/data/client_side_encryption/fle2-FindOneAndUpdate.yml +2 -2
  98. data/spec/spec_tests/data/client_side_encryption/fle2-InsertFind-Indexed.yml +1 -1
  99. data/spec/spec_tests/data/client_side_encryption/fle2-Update.yml +2 -2
  100. data/spec/spec_tests/data/client_side_encryption/unified/addKeyAltName.yml +194 -0
  101. data/spec/spec_tests/data/client_side_encryption/unified/createDataKey-kms_providers-invalid.yml +67 -0
  102. data/spec/spec_tests/data/client_side_encryption/unified/createDataKey.yml +309 -0
  103. data/spec/spec_tests/data/client_side_encryption/unified/deleteKey.yml +159 -0
  104. data/spec/spec_tests/data/client_side_encryption/unified/getKey.yml +105 -0
  105. data/spec/spec_tests/data/client_side_encryption/unified/getKeyByAltName.yml +104 -0
  106. data/spec/spec_tests/data/client_side_encryption/unified/getKeys.yml +122 -0
  107. data/spec/spec_tests/data/client_side_encryption/unified/removeKeyAltName.yml +157 -0
  108. data/spec/spec_tests/data/client_side_encryption/unified/rewrapManyDataKey-decrypt_failure.yml +69 -0
  109. data/spec/spec_tests/data/client_side_encryption/unified/rewrapManyDataKey-encrypt_failure.yml +122 -0
  110. data/spec/spec_tests/data/client_side_encryption/unified/rewrapManyDataKey.yml +432 -0
  111. data/spec/spec_tests/data/client_side_encryption/validatorAndPartialFieldExpression.yml +166 -0
  112. data/spec/spec_tests/data/command_monitoring_unified/bulkWrite.yml +68 -0
  113. data/spec/spec_tests/data/command_monitoring_unified/command.yml +50 -0
  114. data/spec/spec_tests/data/command_monitoring_unified/deleteMany.yml +79 -0
  115. data/spec/spec_tests/data/command_monitoring_unified/deleteOne.yml +79 -0
  116. data/spec/spec_tests/data/command_monitoring_unified/find.yml +254 -0
  117. data/spec/spec_tests/data/command_monitoring_unified/insertMany.yml +79 -0
  118. data/spec/spec_tests/data/command_monitoring_unified/insertOne.yml +77 -0
  119. data/spec/spec_tests/data/command_monitoring_unified/unacknowledgedBulkWrite.yml +55 -0
  120. data/spec/spec_tests/data/command_monitoring_unified/updateMany.yml +87 -0
  121. data/spec/spec_tests/data/command_monitoring_unified/updateOne.yml +118 -0
  122. data/spec/spec_tests/data/crud_unified/distinct-comment.yml +98 -0
  123. data/spec/spec_tests/data/gridfs_unified/delete.yml +198 -0
  124. data/spec/spec_tests/data/gridfs_unified/download.yml +241 -0
  125. data/spec/spec_tests/data/gridfs_unified/downloadByName.yml +159 -0
  126. data/spec/spec_tests/data/gridfs_unified/upload-disableMD5.yml +92 -0
  127. data/spec/spec_tests/data/gridfs_unified/upload.yml +288 -0
  128. data/spec/spec_tests/gridfs_unified_spec.rb +13 -0
  129. data/spec/stress/connection_pool_timing_spec.rb +2 -2
  130. data/spec/support/background_thread_registry.rb +3 -13
  131. data/spec/support/certificates/atlas-ocsp-ca.crt +40 -47
  132. data/spec/support/certificates/atlas-ocsp.crt +101 -106
  133. data/spec/support/crypt.rb +57 -13
  134. data/spec/support/macros.rb +10 -0
  135. data/spec/support/spec_config.rb +4 -0
  136. data.tar.gz.sig +0 -0
  137. metadata +1271 -1219
  138. metadata.gz.sig +0 -0
  139. data/spec/spec_tests/command_monitoring_spec.rb +0 -71
  140. data/spec/spec_tests/data/command_monitoring/bulkWrite.yml +0 -49
  141. data/spec/spec_tests/data/command_monitoring/command.yml +0 -61
  142. data/spec/spec_tests/data/command_monitoring/deleteMany.yml +0 -55
  143. data/spec/spec_tests/data/command_monitoring/deleteOne.yml +0 -55
  144. data/spec/spec_tests/data/command_monitoring/find.yml +0 -266
  145. data/spec/spec_tests/data/command_monitoring/insertMany.yml +0 -75
  146. data/spec/spec_tests/data/command_monitoring/insertOne.yml +0 -51
  147. data/spec/spec_tests/data/command_monitoring/unacknowledgedBulkWrite.yml +0 -34
  148. data/spec/spec_tests/data/command_monitoring/updateMany.yml +0 -65
  149. data/spec/spec_tests/data/command_monitoring/updateOne.yml +0 -90
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 27dd7818b5dc4a0b930ad91ec1607720ad7a02b1b6ea801499e7102ad758db17
4
- data.tar.gz: 7c06c0a8e70f17a81529b727fcecb10c6a39c04fd36111cac51d3802b1494bf0
3
+ metadata.gz: b1a032a8e48c1bc78d55d09cf8b607ec98402fb5f5e4a9a3fd11c566ee74b84f
4
+ data.tar.gz: 4ed2f33af97f4e5ab3da1b6acad5c90f3d7bfd0baee576d8e1df1b246b60637e
5
5
  SHA512:
6
- metadata.gz: 6551874d18d17670e04c13a05ec7e1ee793dfe5984933dbd476adf12603d65ff36c377681d5eb49b94b8da9523d8e196a306da8f3496b0400f6c82302db9b4ea
7
- data.tar.gz: f337ac92bc26479b70ce26a6c88056a57ee2201c586fa134ead68ad00041368fd77edb4c07d7db7e042d1525aeca75998c51e6209b77069b752739cc68d96aae
6
+ metadata.gz: 148a1228124e7895b96ef7931d7ba480748464f730e42c384da5ee64806bc173691db11d278cf7f189fefb4b06c1fe6999ac7cad1934f9dfdbd84a4cb89427a8
7
+ data.tar.gz: e9d7cc2c3dd95b8e2cdbc0017d12fcf7d10df4416999356709029c466f74f8ac07cbe5a868a3bd0392ea6a9d380f8cdba73ad0970fe249048832ad0a11983f47
checksums.yaml.gz.sig CHANGED
Binary file
@@ -115,7 +115,7 @@ module Mongo
115
115
  # )
116
116
  #
117
117
  # @param [ Mongo::Collection ] collection The collection.
118
- # @param [ Array<Hash, BSON::Document> ] requests The requests.
118
+ # @param [ Array<Hash, BSON::Document> ] requests The requests, cannot be empty.
119
119
  # @param [ Hash, BSON::Document ] options The options.
120
120
  #
121
121
  # @since 2.1.0
@@ -324,9 +324,15 @@ module Mongo
324
324
  # and some which are not), in which case the driver expects the server to
325
325
  # fail the operation with an error.
326
326
  #
327
- # @raise [ Error::InvalidUpdateDocument, Error::InvalidReplacementDocument ]
327
+ # Raise an ArgumentError if requests is empty.
328
+ #
329
+ # @raise [ Error::InvalidUpdateDocument, Error::InvalidReplacementDocument,
330
+ # ArgumentError ]
328
331
  # if the document is invalid.
329
332
  def validate_requests!
333
+ if @requests.empty?
334
+ raise ArgumentError, "Bulk write requests cannot be empty"
335
+ end
330
336
  @requests.each do |req|
331
337
  if op = req.keys.first
332
338
  if [:update_one, :update_many].include?(op)
data/lib/mongo/client.rb CHANGED
@@ -268,7 +268,7 @@ module Mongo
268
268
  # @option options [ Integer ] :max_idle_time The maximum seconds a socket can remain idle
269
269
  # since it has been checked in to the pool.
270
270
  # @option options [ Integer ] :max_pool_size The maximum size of the
271
- # connection pool.
271
+ # connection pool. Setting this option to zero creates an unlimited connection pool.
272
272
  # @option options [ Integer ] :max_read_retries The maximum number of read
273
273
  # retries when legacy read retries are in use.
274
274
  # @option options [ Integer ] :max_write_retries The maximum number of write
@@ -437,7 +437,8 @@ module Mongo
437
437
  # are :aws, :azure, :gcp, :kmip, :local. There may be more than one
438
438
  # kms provider specified.
439
439
  # - :schema_map => Hash | nil, JSONSchema for one or more collections
440
- # specifying which fields should be encrypted.
440
+ # specifying which fields should be encrypted. This option is
441
+ # mutually exclusive with :schema_map_path.
441
442
  # - Note: Schemas supplied in the schema_map only apply to configuring
442
443
  # automatic encryption for client side encryption. Other validation
443
444
  # rules in the JSON schema will not be enforced by the driver and will
@@ -448,6 +449,9 @@ module Mongo
448
449
  # the client into sending unencrypted data that should be encrypted.
449
450
  # - Note: If a collection is present on both the :encrypted_fields_map
450
451
  # and :schema_map, an error will be raised.
452
+ # - :schema_map_path => String | nil A path to a file contains the JSON schema
453
+ # of the collection that stores auto encrypted documents. This option is
454
+ # mutually exclusive with :schema_map.
451
455
  # - :bypass_auto_encryption => Boolean, when true, disables auto encryption;
452
456
  # defaults to false.
453
457
  # - :extra_options => Hash | nil, options related to spawning mongocryptd
@@ -763,7 +767,7 @@ module Mongo
763
767
  # We can't use the same cluster if some options that would affect it
764
768
  # have changed.
765
769
  if cluster_modifying?(opts)
766
- Cluster.create(client)
770
+ Cluster.create(client, monitoring: opts[:monitoring])
767
771
  end
768
772
  end
769
773
  end
@@ -1053,6 +1057,11 @@ module Mongo
1053
1057
  # Only recognized by server versions 4.0+.
1054
1058
  # @option options [ Object ] :comment A user-provided
1055
1059
  # comment to attach to this command.
1060
+ # @option options [ Boolean ] :show_expanded_events Enables the server to
1061
+ # send the 'expanded' list of change stream events. The list of additional
1062
+ # events included with this flag set are: createIndexes, dropIndexes,
1063
+ # modify, create, shardCollection, reshardCollection,
1064
+ # refineCollectionShardKey.
1056
1065
  #
1057
1066
  # @note A change stream only allows 'majority' read concern.
1058
1067
  # @note This helper method is preferable to running a raw aggregation with a $changeStream
@@ -1064,8 +1073,11 @@ module Mongo
1064
1073
  def watch(pipeline = [], options = {})
1065
1074
  return use(Database::ADMIN).watch(pipeline, options) unless database.name == Database::ADMIN
1066
1075
 
1076
+ view_options = options.dup
1077
+ view_options[:await_data] = true if options[:max_await_time_ms]
1078
+
1067
1079
  Mongo::Collection::View::ChangeStream.new(
1068
- Mongo::Collection::View.new(self["#{Database::COMMAND}.aggregate"]),
1080
+ Mongo::Collection::View.new(self["#{Database::COMMAND}.aggregate"], {}, view_options),
1069
1081
  pipeline,
1070
1082
  Mongo::Collection::View::ChangeStream::CLUSTER,
1071
1083
  options)
@@ -1544,7 +1556,9 @@ module Mongo
1544
1556
  def validate_max_min_pool_size!(option, opts)
1545
1557
  if option == :min_pool_size && opts[:min_pool_size]
1546
1558
  max = opts[:max_pool_size] || Server::ConnectionPool::DEFAULT_MAX_SIZE
1547
- raise Error::InvalidMinPoolSize.new(opts[:min_pool_size], max) unless opts[:min_pool_size] <= max
1559
+ if max != 0 && opts[:min_pool_size] > max
1560
+ raise Error::InvalidMinPoolSize.new(opts[:min_pool_size], max)
1561
+ end
1548
1562
  end
1549
1563
  true
1550
1564
  end
@@ -43,7 +43,7 @@ module Mongo
43
43
  #
44
44
  # @raise [ ArgumentError ] If required options are missing or incorrectly
45
45
  # formatted.
46
- def initialize(key_vault_client, options={})
46
+ def initialize(key_vault_client, options = {})
47
47
  @encrypter = Crypt::ExplicitEncrypter.new(
48
48
  key_vault_client,
49
49
  options[:key_vault_namespace],
@@ -71,13 +71,19 @@ module Mongo
71
71
  # will not be properly parsed.
72
72
  # @option options [ Array<String> ] :key_alt_names An optional array of
73
73
  # strings specifying alternate names for the new data key.
74
+ # @option options [ String | nil ] :key_material Optional
75
+ # 96 bytes to use as custom key material for the data key being created.
76
+ # If :key_material option is given, the custom key material is used
77
+ # for encrypting and decrypting data.
74
78
  #
75
79
  # @return [ BSON::Binary ] The 16-byte UUID of the new data key as a
76
80
  # BSON::Binary object with type :uuid.
77
81
  def create_data_key(kms_provider, options={})
78
82
  key_document = Crypt::KMS::MasterKeyDocument.new(kms_provider, options)
83
+
79
84
  key_alt_names = options[:key_alt_names]
80
- @encrypter.create_and_insert_data_key(key_document, key_alt_names)
85
+ key_material = options[:key_material]
86
+ @encrypter.create_and_insert_data_key(key_document, key_alt_names, key_material)
81
87
  end
82
88
 
83
89
  # Encrypts a value using the specified encryption key and algorithm.
@@ -97,10 +103,10 @@ module Mongo
97
103
  # to be applied if encryption algorithm is set to "Indexed". If not
98
104
  # provided, it defaults to a value of 0. Contention factor should be set
99
105
  # only if encryption algorithm is set to "Indexed".
100
- # @option options [ Symbol ] query_type Query type to be applied
106
+ # @option options [ String | nil ] query_type Query type to be applied
101
107
  # if encryption algorithm is set to "Indexed". Query type should be set
102
108
  # only if encryption algorithm is set to "Indexed". The only allowed
103
- # value is :equality.
109
+ # value is "equality".
104
110
  #
105
111
  # @note The :key_id and :key_alt_name options are mutually exclusive. Only
106
112
  # one is required to perform explicit encryption.
@@ -123,5 +129,81 @@ module Mongo
123
129
  def decrypt(value)
124
130
  @encrypter.decrypt(value)
125
131
  end
132
+
133
+ # Adds a key_alt_name for the key in the key vault collection with the given id.
134
+ #
135
+ # @param [ BSON::Binary ] id Id of the key to add new key alt name.
136
+ # @param [ String ] key_alt_name New key alt name to add.
137
+ #
138
+ # @return [ BSON::Document | nil ] Document describing the identified key
139
+ # before adding the key alt name, or nil if no such key.
140
+ def add_key_alt_name(id, key_alt_name)
141
+ @encrypter.add_key_alt_name(id, key_alt_name)
142
+ end
143
+
144
+ # Removes the key with the given id from the key vault collection.
145
+ #
146
+ # @param [ BSON::Binary ] id Id of the key to delete.
147
+ #
148
+ # @return [ Operation::Result ] The response from the database for the delete_one
149
+ # operation that deletes the key.
150
+ def delete_key(id)
151
+ @encrypter.delete_key(id)
152
+ end
153
+
154
+ # Finds a single key with the given id.
155
+ #
156
+ # @param [ BSON::Binary ] id Id of the key to get.
157
+ #
158
+ # @return [ BSON::Document | nil ] The found key document or nil
159
+ # if not found.
160
+ def get_key(id)
161
+ @encrypter.get_key(id)
162
+ end
163
+
164
+ # Returns a key in the key vault collection with the given key_alt_name.
165
+ #
166
+ # @param [ String ] key_alt_name Key alt name to find a key.
167
+ #
168
+ # @return [ BSON::Document | nil ] The found key document or nil
169
+ # if not found.
170
+ def get_key_by_alt_name(key_alt_name)
171
+ @encrypter.get_key_by_alt_name(key_alt_name)
172
+ end
173
+
174
+ # Returns all keys in the key vault collection.
175
+ #
176
+ # @return [ Collection::View ] Keys in the key vault collection.
177
+ def get_keys
178
+ @encrypter.get_keys
179
+ end
180
+ alias :keys :get_keys
181
+
182
+ # Removes a key_alt_name from a key in the key vault collection with the given id.
183
+ #
184
+ # @param [ BSON::Binary ] id Id of the key to remove key alt name.
185
+ # @param [ String ] key_alt_name Key alt name to remove.
186
+ #
187
+ # @return [ BSON::Document | nil ] Document describing the identified key
188
+ # before removing the key alt name, or nil if no such key.
189
+ def remove_key_alt_name(id, key_alt_name)
190
+ @encrypter.remove_key_alt_name(id, key_alt_name)
191
+ end
192
+
193
+ # Decrypts multiple data keys and (re-)encrypts them with a new master_key,
194
+ # or with their current master_key if a new one is not given.
195
+ #
196
+ # @param [ Hash ] filter Filter used to find keys to be updated.
197
+ # @param [ Hash ] options
198
+ #
199
+ # @option options [ String ] :provider KMS provider to encrypt keys.
200
+ # @option options [ Hash | nil ] :master_key Document describing master key
201
+ # to encrypt keys.
202
+ #
203
+ # @return [ Crypt::RewrapManyDataKeyResult ] Result of the operation.
204
+ def rewrap_many_data_key(filter, opts = {})
205
+ @encrypter.rewrap_many_data_key(filter, opts)
206
+ end
207
+
126
208
  end
127
209
  end
data/lib/mongo/cluster.rb CHANGED
@@ -280,20 +280,22 @@ module Mongo
280
280
  # Create a cluster for the provided client, for use when we don't want the
281
281
  # client's original cluster instance to be the same.
282
282
  #
283
- # @api private
284
- #
285
283
  # @example Create a cluster for the client.
286
284
  # Cluster.create(client)
287
285
  #
288
286
  # @param [ Client ] client The client to create on.
287
+ # @param [ Monitoring | nil ] monitoring. The monitoring instance to use
288
+ # with the new cluster. If nil, a new instance of Monitoring will be
289
+ # created.
289
290
  #
290
291
  # @return [ Cluster ] The cluster.
291
292
  #
292
293
  # @since 2.0.0
293
- def self.create(client)
294
+ # @api private
295
+ def self.create(client, monitoring: nil)
294
296
  cluster = Cluster.new(
295
297
  client.cluster.addresses.map(&:to_s),
296
- Monitoring.new,
298
+ monitoring || Monitoring.new,
297
299
  client.cluster_options,
298
300
  )
299
301
  client.instance_variable_set(:@cluster, cluster)
@@ -97,6 +97,9 @@ module Mongo
97
97
  def initialize(view, pipeline, options = {})
98
98
  @view = view
99
99
  @pipeline = pipeline.dup
100
+ unless Mongo.broken_view_aggregate || view.filter.empty?
101
+ @pipeline.unshift(:$match => view.filter)
102
+ end
100
103
  @options = BSON::Document.new(options).freeze
101
104
  end
102
105
 
@@ -115,6 +115,11 @@ module Mongo
115
115
  # dropped and recreated or newly renamed collections without missing any notifications.
116
116
  # @option options [ Object ] :comment A user-provided
117
117
  # comment to attach to this command.
118
+ # @option options [ Boolean ] :show_expanded_events Enables the server to
119
+ # send the 'expanded' list of change stream events. The list of additional
120
+ # events included with this flag set are: createIndexes, dropIndexes,
121
+ # modify, create, shardCollection, reshardCollection,
122
+ # refineCollectionShardKey.
118
123
  #
119
124
  # The server will report an error if `startAfter` and `resumeAfter` are both specified.
120
125
  #
@@ -343,6 +348,10 @@ module Mongo
343
348
  doc[:fullDocumentBeforeChange] = @options[:full_document_before_change]
344
349
  end
345
350
 
351
+ if @options.key?(:show_expanded_events)
352
+ doc[:showExpandedEvents] = @options[:show_expanded_events]
353
+ end
354
+
346
355
  if resuming?
347
356
  # We have a resume token once we retrieved any documents.
348
357
  # However, if the first getMore fails and the user didn't pass
@@ -170,6 +170,7 @@ module Mongo
170
170
  max_time_ms: options[:max_time_ms],
171
171
  max_value: options[:max_value],
172
172
  min_value: options[:min_value],
173
+ no_cursor_timeout: options[:no_cursor_timeout],
173
174
  return_key: options[:return_key],
174
175
  show_disk_loc: options[:show_disk_loc],
175
176
  comment: options[:comment],
@@ -58,6 +58,7 @@ module Mongo
58
58
  #
59
59
  # @since 2.0.0
60
60
  def aggregate(pipeline, options = {})
61
+ options = @options.merge(options) unless Mongo.broken_view_options
61
62
  aggregation = Aggregation.new(self, pipeline, options)
62
63
 
63
64
  # Because the $merge and $out pipeline stages write documents to the
@@ -167,6 +168,7 @@ module Mongo
167
168
  # * $near should be replaced with $geoWithin with $center
168
169
  # * $nearSphere should be replaced with $geoWithin with $centerSphere
169
170
  def count(opts = {})
171
+ opts = @options.merge(opts) unless Mongo.broken_view_options
170
172
  cmd = { :count => collection.name, :query => filter }
171
173
  cmd[:skip] = opts[:skip] if opts[:skip]
172
174
  cmd[:hint] = opts[:hint] if opts[:hint]
@@ -219,12 +221,13 @@ module Mongo
219
221
  #
220
222
  # @since 2.6.0
221
223
  def count_documents(opts = {})
224
+ opts = @options.merge(opts) unless Mongo.broken_view_options
222
225
  pipeline = [:'$match' => filter]
223
226
  pipeline << { :'$skip' => opts[:skip] } if opts[:skip]
224
227
  pipeline << { :'$limit' => opts[:limit] } if opts[:limit]
225
228
  pipeline << { :'$group' => { _id: 1, n: { :'$sum' => 1 } } }
226
229
 
227
- opts = opts.select { |k, _| [:hint, :max_time_ms, :read, :collation, :session, :comment].include?(k) }
230
+ opts = opts.slice(:hint, :max_time_ms, :read, :collation, :session, :comment)
228
231
  opts[:collation] ||= collation
229
232
 
230
233
  first = aggregate(pipeline, opts).first
@@ -254,11 +257,12 @@ module Mongo
254
257
  end
255
258
 
256
259
  %i[limit skip].each do |opt|
257
- if @options.key?(opt)
260
+ if options.key?(opt) || opts.key?(opt)
258
261
  raise ArgumentError, "Cannot call estimated_document_count when querying with #{opt}"
259
262
  end
260
263
  end
261
264
 
265
+ opts = @options.merge(opts) unless Mongo.broken_view_options
262
266
  Mongo::Lint.validate_underscore_read_preference(opts[:read])
263
267
  read_pref = opts[:read] || read_preference
264
268
  selector = ServerSelector.get(read_pref || server_selector)
@@ -305,6 +309,8 @@ module Mongo
305
309
  # command to run.
306
310
  # @option opts [ Hash ] :read The read preference options.
307
311
  # @option opts [ Hash ] :collation The collation to use.
312
+ # @option options [ Object ] :comment A user-provided
313
+ # comment to attach to this command.
308
314
  #
309
315
  # @return [ Array<Object> ] The list of distinct values.
310
316
  #
@@ -313,9 +319,10 @@ module Mongo
313
319
  if field_name.nil?
314
320
  raise ArgumentError, 'Field name for distinct operation must be not nil'
315
321
  end
322
+ opts = @options.merge(opts) unless Mongo.broken_view_options
316
323
  cmd = { :distinct => collection.name,
317
324
  :key => field_name.to_s,
318
- :query => filter }
325
+ :query => filter, }
319
326
  cmd[:maxTimeMS] = opts[:max_time_ms] if opts[:max_time_ms]
320
327
  if read_concern
321
328
  cmd[:readConcern] = Options::Mapper.transform_values_to_strings(
@@ -332,6 +339,7 @@ module Mongo
332
339
  options: {:limit => -1},
333
340
  read: read_pref,
334
341
  session: session,
342
+ comment: opts[:comment],
335
343
  # For some reason collation was historically accepted as a
336
344
  # string key. Note that this isn't documented as valid usage.
337
345
  collation: opts[:collation] || opts['collation'] || collation,
@@ -72,6 +72,7 @@ module Mongo
72
72
  :change_stream_pre_and_post_images => :changeStreamPreAndPostImages,
73
73
  :encrypted_fields => :encryptedFields,
74
74
  :validator => :validator,
75
+ :view_on => :viewOn
75
76
  }
76
77
 
77
78
  # Check if a collection is equal to another object. Will check the name and
@@ -482,6 +483,11 @@ module Mongo
482
483
  # Only recognized by server versions 4.0+.
483
484
  # @option options [ Object ] :comment A user-provided
484
485
  # comment to attach to this command.
486
+ # @option options [ Boolean ] :show_expanded_events Enables the server to
487
+ # send the 'expanded' list of change stream events. The list of additional
488
+ # events included with this flag set are: createIndexes, dropIndexes,
489
+ # modify, create, shardCollection, reshardCollection,
490
+ # refineCollectionShardKey.
485
491
  #
486
492
  # @note A change stream only allows 'majority' read concern.
487
493
  # @note This helper method is preferable to running a raw aggregation with
@@ -491,7 +497,9 @@ module Mongo
491
497
  #
492
498
  # @since 2.5.0
493
499
  def watch(pipeline = [], options = {})
494
- View::ChangeStream.new(View.new(self, {}, options), pipeline, nil, options)
500
+ view_options = options.dup
501
+ view_options[:await_data] = true if options[:max_await_time_ms]
502
+ View::ChangeStream.new(View.new(self, {}, view_options), pipeline, nil, options)
495
503
  end
496
504
 
497
505
  # Gets an estimated number of matching documents in the collection.
data/lib/mongo/config.rb CHANGED
@@ -13,6 +13,17 @@ module Mongo
13
13
  extend Options
14
14
  extend self
15
15
 
16
+ # When this flag is off, an aggregation done on a view will be executed over
17
+ # the documents included in that view, instead of all documents in the
18
+ # collection. When this flag is on, the view fiter is ignored.
19
+ option :broken_view_aggregate, default: true
20
+
21
+ # When this flag is set to false, the view options will be correctly
22
+ # propagated to readable methods.
23
+ option :broken_view_options, default: true
24
+
25
+ # When this flag is set to true, the update and replace methods will
26
+ # validate the paramters and raise an error if they are invalid.
16
27
  option :validate_update_replace, default: false
17
28
 
18
29
  # Set the configuration options.
@@ -57,7 +57,10 @@ module Mongo
57
57
  # @option options [ String ] :key_vault_namespace The namespace of the key
58
58
  # vault in the format database.collection.
59
59
  # @option options [ Hash | nil ] :schema_map The JSONSchema of the collection(s)
60
- # with encrypted fields.
60
+ # with encrypted fields. This option is mutually exclusive with :schema_map_path.
61
+ # @option options [ String | nil ] :schema_map_path A path to a file contains the JSON schema
62
+ # of the collection that stores auto encrypted documents. This option is
63
+ # mutually exclusive with :schema_map.
61
64
  # @option options [ Boolean | nil ] :bypass_auto_encryption When true, disables
62
65
  # auto-encryption. Default is false.
63
66
  # @option options [ Hash | nil ] :extra_options Options related to spawning
@@ -82,12 +85,15 @@ module Mongo
82
85
  # @raise [ ArgumentError ] If required options are missing or incorrectly
83
86
  # formatted.
84
87
  def initialize(options)
88
+ # Note that this call may eventually, via other method invocations,
89
+ # create additional clients which have to be cleaned up.
85
90
  @options = set_default_options(options).freeze
86
91
 
87
92
  @crypt_handle = Crypt::Handle.new(
88
93
  Crypt::KMS::Credentials.new(@options[:kms_providers]),
89
94
  Crypt::KMS::Validations.validate_tls_options(@options[:kms_tls_options]),
90
95
  schema_map: @options[:schema_map],
96
+ schema_map_path: @options[:schema_map_path],
91
97
  encrypted_fields_map: @options[:encrypted_fields_map],
92
98
  bypass_query_analysis: @options[:bypass_query_analysis]
93
99
  )
@@ -119,6 +125,30 @@ module Mongo
119
125
  end
120
126
  raise
121
127
  end
128
+ rescue
129
+ if @key_vault_client && @key_vault_client != options[:client] &&
130
+ @key_vault_client.cluster != options[:client].cluster
131
+ then
132
+ begin
133
+ @key_vault_client.close
134
+ rescue => e
135
+ log_warn("Error closing key vault client in auto encrypter's constructor: #{e.class}: #{e}")
136
+ # Drop this exception so that the original exception is raised
137
+ end
138
+ end
139
+
140
+ if @metadata_client && @metadata_client != options[:client] &&
141
+ @metadata_client.cluster != options[:client].cluster
142
+ then
143
+ begin
144
+ @metadata_client.close
145
+ rescue => e
146
+ log_warn("Error closing metadata client in auto encrypter's constructor: #{e.class}: #{e}")
147
+ # Drop this exception so that the original exception is raised
148
+ end
149
+ end
150
+
151
+ raise
122
152
  end
123
153
 
124
154
  # Whether this encrypter should perform encryption (returns false if
@@ -164,6 +194,18 @@ module Mongo
164
194
  def close
165
195
  @mongocryptd_client.close if @mongocryptd_client
166
196
 
197
+ if @key_vault_client && @key_vault_client != options[:client] &&
198
+ @key_vault_client.cluster != options[:client].cluster
199
+ then
200
+ @key_vault_client.close
201
+ end
202
+
203
+ if @metadata_client && @metadata_client != options[:client] &&
204
+ @metadata_client.cluster != options[:client].cluster
205
+ then
206
+ @metadata_client.close
207
+ end
208
+
167
209
  true
168
210
  end
169
211
 
@@ -206,26 +248,16 @@ module Mongo
206
248
  client = options[:client]
207
249
  @key_vault_client = if options[:key_vault_client]
208
250
  options[:key_vault_client]
209
- # https://jira.mongodb.org/browse/RUBY-3010
210
- # https://jira.mongodb.org/browse/RUBY-3011
211
- # Specification requires to use existing client when connection pool
212
- # size is unlimited (0). Ruby driver does not support unlimited pool
213
- # size.
214
- # elsif client.options[:max_pool_size] == 0
215
- # client
251
+ elsif client.options[:max_pool_size] == 0
252
+ client
216
253
  else
217
254
  internal_client(client)
218
255
  end
219
256
 
220
257
  @metadata_client = if options[:bypass_auto_encryption]
221
258
  nil
222
- # Specification requires to use existing client when connection pool
223
- # size is unlimited (0). Ruby driver does not support unlimited pool
224
- # size.
225
- # https://jira.mongodb.org/browse/RUBY-3010
226
- # https://jira.mongodb.org/browse/RUBY-3011
227
- # elsif client.options[:max_pool_size] == 0
228
- # client
259
+ elsif client.options[:max_pool_size] == 0
260
+ client
229
261
  else
230
262
  internal_client(client)
231
263
  end
@@ -242,12 +274,8 @@ module Mongo
242
274
  def internal_client(client)
243
275
  @internal_client ||= client.with(
244
276
  auto_encryption_options: nil,
245
- # Specification requires that the internal client's connection pool
246
- # size is unlimited (0). Ruby driver does not support unlimited pool
247
- # size.
248
- # https://jira.mongodb.org/browse/RUBY-3010
249
- # https://jira.mongodb.org/browse/RUBY-3011
250
- # max_pool_size: 0
277
+ min_pool_size: 0,
278
+ monitoring: client.send(:monitoring),
251
279
  )
252
280
  end
253
281
  end