mongo 2.18.0 → 2.18.2

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 (118) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/lib/mongo/bulk_write.rb +7 -5
  4. data/lib/mongo/client.rb +1 -1
  5. data/lib/mongo/collection/view/writable.rb +0 -2
  6. data/lib/mongo/collection.rb +150 -45
  7. data/lib/mongo/crypt/auto_encrypter.rb +30 -9
  8. data/lib/mongo/crypt/binding.rb +93 -1
  9. data/lib/mongo/crypt/explicit_encrypter.rb +5 -1
  10. data/lib/mongo/crypt/handle.rb +33 -0
  11. data/lib/mongo/crypt/kms.rb +0 -1
  12. data/lib/mongo/cursor.rb +6 -1
  13. data/lib/mongo/error/invalid_read_option.rb +1 -1
  14. data/lib/mongo/operation/aggregate.rb +1 -2
  15. data/lib/mongo/operation/collections_info.rb +3 -15
  16. data/lib/mongo/operation/command.rb +1 -2
  17. data/lib/mongo/operation/count.rb +1 -2
  18. data/lib/mongo/operation/create.rb +1 -2
  19. data/lib/mongo/operation/create_index.rb +1 -2
  20. data/lib/mongo/operation/create_user.rb +1 -2
  21. data/lib/mongo/operation/delete.rb +0 -1
  22. data/lib/mongo/operation/distinct.rb +1 -2
  23. data/lib/mongo/operation/drop.rb +1 -2
  24. data/lib/mongo/operation/drop_database.rb +1 -2
  25. data/lib/mongo/operation/drop_index.rb +1 -2
  26. data/lib/mongo/operation/explain.rb +1 -3
  27. data/lib/mongo/operation/find/builder.rb +0 -1
  28. data/lib/mongo/operation/find.rb +1 -3
  29. data/lib/mongo/operation/get_more.rb +1 -3
  30. data/lib/mongo/operation/indexes.rb +1 -17
  31. data/lib/mongo/operation/insert.rb +0 -1
  32. data/lib/mongo/operation/kill_cursors.rb +1 -2
  33. data/lib/mongo/operation/list_collections.rb +1 -2
  34. data/lib/mongo/operation/map_reduce.rb +1 -2
  35. data/lib/mongo/operation/parallel_scan.rb +1 -2
  36. data/lib/mongo/operation/remove_user.rb +1 -2
  37. data/lib/mongo/operation/shared/{polymorphic_operation.rb → op_msg_executable.rb} +11 -6
  38. data/lib/mongo/operation/shared/sessions_supported.rb +7 -3
  39. data/lib/mongo/operation/update.rb +0 -1
  40. data/lib/mongo/operation/update_user.rb +1 -2
  41. data/lib/mongo/operation/users_info.rb +1 -2
  42. data/lib/mongo/operation/write_command.rb +1 -2
  43. data/lib/mongo/operation.rb +1 -3
  44. data/lib/mongo/protocol.rb +0 -3
  45. data/lib/mongo/query_cache.rb +20 -20
  46. data/lib/mongo/session.rb +1 -1
  47. data/lib/mongo/version.rb +1 -1
  48. data/spec/README.md +5 -1
  49. data/spec/integration/bulk_write_spec.rb +16 -0
  50. data/spec/integration/command_spec.rb +1 -23
  51. data/spec/integration/ocsp_verifier_spec.rb +2 -0
  52. data/spec/mongo/client_construction_spec.rb +4 -4
  53. data/spec/mongo/collection_crud_spec.rb +56 -0
  54. data/spec/mongo/collection_spec.rb +11 -1
  55. data/spec/mongo/crypt/auto_encrypter_spec.rb +41 -6
  56. data/spec/mongo/crypt/binding/version_spec.rb +8 -0
  57. data/spec/mongo/crypt/handle_spec.rb +102 -0
  58. data/spec/mongo/crypt/kms_spec.rb +12 -9
  59. data/spec/mongo/cursor_spec.rb +50 -0
  60. data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
  61. data/spec/spec_tests/data/change_streams_unified/change-streams-resume-errorLabels.yml +3 -0
  62. data/spec/spec_tests/data/client_side_encryption/unified/rewrapManyDataKey.yml +3 -3
  63. data/spec/spec_tests/data/sdam_integration/hello-command-error.yml +6 -14
  64. data/spec/spec_tests/data/sdam_integration/hello-network-error.yml +4 -14
  65. data/spec/spec_tests/data/sdam_integration/hello-timeout.yml +8 -14
  66. data/spec/spec_tests/data/transactions_unified/do-not-retry-read-in-transaction.yml +64 -0
  67. data/spec/spec_tests/data/transactions_unified/retryable-abort-handshake.yml +118 -0
  68. data/spec/spec_tests/data/transactions_unified/retryable-commit-handshake.yml +118 -0
  69. data/spec/support/certificates/retrieve-atlas-cert +38 -0
  70. data/spec/support/spec_config.rb +4 -0
  71. data.tar.gz.sig +0 -0
  72. metadata +1133 -1178
  73. metadata.gz.sig +0 -0
  74. data/lib/mongo/operation/aggregate/command.rb +0 -55
  75. data/lib/mongo/operation/collections_info/command.rb +0 -48
  76. data/lib/mongo/operation/command/command.rb +0 -41
  77. data/lib/mongo/operation/count/command.rb +0 -47
  78. data/lib/mongo/operation/create/command.rb +0 -47
  79. data/lib/mongo/operation/create_index/command.rb +0 -61
  80. data/lib/mongo/operation/create_user/command.rb +0 -46
  81. data/lib/mongo/operation/delete/command.rb +0 -52
  82. data/lib/mongo/operation/distinct/command.rb +0 -47
  83. data/lib/mongo/operation/drop/command.rb +0 -41
  84. data/lib/mongo/operation/drop_database/command.rb +0 -41
  85. data/lib/mongo/operation/drop_index/command.rb +0 -45
  86. data/lib/mongo/operation/explain/command.rb +0 -58
  87. data/lib/mongo/operation/explain/legacy.rb +0 -52
  88. data/lib/mongo/operation/find/builder/legacy.rb +0 -123
  89. data/lib/mongo/operation/find/command.rb +0 -51
  90. data/lib/mongo/operation/find/legacy/result.rb +0 -46
  91. data/lib/mongo/operation/find/legacy.rb +0 -52
  92. data/lib/mongo/operation/get_more/command.rb +0 -43
  93. data/lib/mongo/operation/get_more/legacy.rb +0 -39
  94. data/lib/mongo/operation/indexes/command.rb +0 -42
  95. data/lib/mongo/operation/indexes/legacy.rb +0 -48
  96. data/lib/mongo/operation/insert/command.rb +0 -55
  97. data/lib/mongo/operation/kill_cursors/command.rb +0 -48
  98. data/lib/mongo/operation/list_collections/command.rb +0 -46
  99. data/lib/mongo/operation/map_reduce/command.rb +0 -51
  100. data/lib/mongo/operation/parallel_scan/command.rb +0 -57
  101. data/lib/mongo/operation/remove_user/command.rb +0 -46
  102. data/lib/mongo/operation/shared/op_msg_or_command.rb +0 -41
  103. data/lib/mongo/operation/shared/op_msg_or_find_command.rb +0 -44
  104. data/lib/mongo/operation/update/command.rb +0 -53
  105. data/lib/mongo/operation/update_user/command.rb +0 -45
  106. data/lib/mongo/operation/users_info/command.rb +0 -46
  107. data/lib/mongo/operation/write_command/command.rb +0 -51
  108. data/lib/mongo/protocol/delete.rb +0 -172
  109. data/lib/mongo/protocol/insert.rb +0 -181
  110. data/lib/mongo/protocol/update.rb +0 -214
  111. data/spec/mongo/operation/delete/command_spec.rb +0 -115
  112. data/spec/mongo/operation/find/legacy_spec.rb +0 -131
  113. data/spec/mongo/operation/get_more_spec.rb +0 -63
  114. data/spec/mongo/operation/insert/command_spec.rb +0 -118
  115. data/spec/mongo/operation/update/command_spec.rb +0 -122
  116. data/spec/mongo/protocol/delete_spec.rb +0 -185
  117. data/spec/mongo/protocol/insert_spec.rb +0 -179
  118. data/spec/mongo/protocol/update_spec.rb +0 -204
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b1a032a8e48c1bc78d55d09cf8b607ec98402fb5f5e4a9a3fd11c566ee74b84f
4
- data.tar.gz: 4ed2f33af97f4e5ab3da1b6acad5c90f3d7bfd0baee576d8e1df1b246b60637e
3
+ metadata.gz: 44bd3e615b9e0e11f3803eae60a44b56fe5be326b7dd8f78b3c5aa42fbf7e621
4
+ data.tar.gz: 124bfd17f02e5b929e8b40dc797146770096270a83f7ea2389890efe83af1fbe
5
5
  SHA512:
6
- metadata.gz: 148a1228124e7895b96ef7931d7ba480748464f730e42c384da5ee64806bc173691db11d278cf7f189fefb4b06c1fe6999ac7cad1934f9dfdbd84a4cb89427a8
7
- data.tar.gz: e9d7cc2c3dd95b8e2cdbc0017d12fcf7d10df4416999356709029c466f74f8ac07cbe5a868a3bd0392ea6a9d380f8cdba73ad0970fe249048832ad0a11983f47
6
+ metadata.gz: 675df13e076a6a8b94e187e493cefb8fe4e1697cafdb4241898519f55b5abf3cceff7db1e9424bc2defdcba5a218e1bd8b149572ab891319c7c8a42f9699706a
7
+ data.tar.gz: 7593ef22c16038dc53e7e4e04c615dbc39c083bdffb6ef7d99f583d64613909079c7edb2b5e367117e0b3dca19a0a57ba3eb0ac92701bde48d750557a17cf567
checksums.yaml.gz.sig CHANGED
Binary file
@@ -115,7 +115,8 @@ module Mongo
115
115
  # )
116
116
  #
117
117
  # @param [ Mongo::Collection ] collection The collection.
118
- # @param [ Array<Hash, BSON::Document> ] requests The requests, cannot be empty.
118
+ # @param [ Enumerable<Hash, BSON::Document> ] requests The requests,
119
+ # cannot be empty.
119
120
  # @param [ Hash, BSON::Document ] options The options.
120
121
  #
121
122
  # @since 2.1.0
@@ -221,7 +222,7 @@ module Mongo
221
222
  def split_execute(name, values, connection, context, operation_id, result_combiner, session, txn_num)
222
223
  execute_operation(name, values.shift(values.size / 2), connection, context, operation_id, result_combiner, session, txn_num)
223
224
 
224
- txn_num = session.next_txn_num if txn_num
225
+ txn_num = session.next_txn_num if txn_num && !session.in_transaction?
225
226
  execute_operation(name, values, connection, context, operation_id, result_combiner, session, txn_num)
226
227
  end
227
228
 
@@ -330,10 +331,9 @@ module Mongo
330
331
  # ArgumentError ]
331
332
  # if the document is invalid.
332
333
  def validate_requests!
333
- if @requests.empty?
334
- raise ArgumentError, "Bulk write requests cannot be empty"
335
- end
334
+ requests_empty = true
336
335
  @requests.each do |req|
336
+ requests_empty = false
337
337
  if op = req.keys.first
338
338
  if [:update_one, :update_many].include?(op)
339
339
  if doc = maybe_first(req.dig(op, :update))
@@ -359,6 +359,8 @@ module Mongo
359
359
  end
360
360
  end
361
361
  end
362
+ end.tap do
363
+ raise ArgumentError, "Bulk write requests cannot be empty" if requests_empty
362
364
  end
363
365
  end
364
366
 
data/lib/mongo/client.rb CHANGED
@@ -1570,7 +1570,7 @@ module Mongo
1570
1570
  # for custom classes implementing key access ([]).
1571
1571
  # Instead reject common cases of strings and symbols.
1572
1572
  if read.is_a?(String) || read.is_a?(Symbol)
1573
- raise Error::InvalidReadOption.new(read, 'must be a hash')
1573
+ raise Error::InvalidReadOption.new(read, "the read preference must be specified as a hash: { mode: #{read.inspect} }")
1574
1574
  end
1575
1575
 
1576
1576
  if mode = read[:mode]
@@ -98,8 +98,6 @@ module Mongo
98
98
  end.first&.fetch('value', nil)
99
99
  end
100
100
 
101
- # db['users'].bulk_write([{insert_one: {x: 1}}, {insert_one: {x: 2}}])
102
-
103
101
  # Finds a single document and replaces it.
104
102
  #
105
103
  # @example Find a document and replace it, returning the original.
@@ -83,7 +83,7 @@ module Mongo
83
83
  #
84
84
  # @param [ Object ] other The object to check.
85
85
  #
86
- # @return [ true, false ] If the objects are equal.
86
+ # @return [ true | false ] If the objects are equal.
87
87
  #
88
88
  # @since 2.0.0
89
89
  def ==(other)
@@ -100,19 +100,59 @@ module Mongo
100
100
  # @param [ String, Symbol ] name The collection name.
101
101
  # @param [ Hash ] options The collection options.
102
102
  #
103
- # @option options [ Hash ] :write Deprecated. Equivalent to :write_concern
103
+ # @option opts [ true | false ] :capped Create a fixed-sized collection.
104
+ # @option opts [ Hash ] :change_stream_pre_and_post_images Used to enable
105
+ # pre- and post-images on the created collection.
106
+ # The hash may have the following items:
107
+ # - *:enabled* -- true or false.
108
+ # @option opts [ Hash ] :clustered_index Create a clustered index.
109
+ # This option specifies how this collection should be clustered on _id.
110
+ # The hash may have the following items:
111
+ # - *:key* -- The clustered index key field. Must be set to { _id: 1 }.
112
+ # - *:unique* -- Must be set to true. The collection will not accept
113
+ # inserted or updated documents where the clustered index key value
114
+ # matches an existing value in the index.
115
+ # - *:name* -- Optional. A name that uniquely identifies the clustered index.
116
+ # @option opts [ Hash ] :collation The collation to use.
117
+ # @option opts [ Hash ] :encrypted_fields Hash describing encrypted fields
118
+ # for queryable encryption.
119
+ # @option opts [ Integer ] :expire_after Number indicating
120
+ # after how many seconds old time-series data should be deleted.
121
+ # @option opts [ Integer ] :max The maximum number of documents in a
122
+ # capped collection. The size limit takes precedents over max.
123
+ # @option opts [ Array<Hash> ] :pipeline An array of pipeline stages.
124
+ # A view will be created by applying this pipeline to the view_on
125
+ # collection or view.
126
+ # @option options [ Hash ] :read_concern The read concern options hash,
127
+ # with the following optional keys:
128
+ # - *:level* -- the read preference level as a symbol; valid values
129
+ # are *:local*, *:majority*, and *:snapshot*
130
+ # @option options [ Hash ] :read The read preference options.
131
+ # The hash may have the following items:
132
+ # - *:mode* -- read preference specified as a symbol; valid values are
133
+ # *:primary*, *:primary_preferred*, *:secondary*, *:secondary_preferred*
134
+ # and *:nearest*.
135
+ # - *:tag_sets* -- an array of hashes.
136
+ # - *:local_threshold*.
137
+ # @option opts [ Session ] :session The session to use for the operation.
138
+ # @option opts [ Integer ] :size The size of the capped collection.
139
+ # @option opts [ Hash ] :time_series Create a time-series collection.
140
+ # The hash may have the following items:
141
+ # - *:timeField* -- The name of the field which contains the date in each
142
+ # time series document.
143
+ # - *:metaField* -- The name of the field which contains metadata in each
144
+ # time series document.
145
+ # - *:granularity* -- Set the granularity to the value that is the closest
146
+ # match to the time span between consecutive incoming measurements.
147
+ # Possible values are "seconds" (default), "minutes", and "hours".
148
+ # @option opts [ Hash ] :validator Hash describing document validation
149
+ # options for the collection.
150
+ # @option opts [ String ] :view_on The name of the source collection or
151
+ # view from which to create a view.
152
+ # @option opts [ Hash ] :write Deprecated. Equivalent to :write_concern
104
153
  # option.
105
- # @option options [ Hash ] :write_concern The write concern options.
154
+ # @option opts [ Hash ] :write_concern The write concern options.
106
155
  # Can be :w => Integer|String, :fsync => Boolean, :j => Boolean.
107
- # @option options [ Hash ] :time_series Create a time-series collection.
108
- # See https://mongodb.com/docs/manual/core/timeseries-collections/ for more
109
- # information about time-series collection.
110
- # @option options [ Integer ] :expire_after Number indicating
111
- # after how many seconds old time-series data should be deleted.
112
- # @options clustered_index [ Hash ] :clustered_index Create a clustered index.
113
- # This option specifies how this collection should be clustered on _id.
114
- # See https://www.mongodb.com/docs/v5.3/reference/method/db.createCollection/#std-label-db.createCollection.clusteredIndex
115
- # for more information about this option.
116
156
  #
117
157
  # @since 2.0.0
118
158
  def initialize(database, name, options = {})
@@ -204,17 +244,37 @@ module Mongo
204
244
  wc
205
245
  end
206
246
 
207
- # Provides a new collection with either a new read preference or new write concern
208
- # merged over the existing read preference / write concern.
247
+ # Provides a new collection with either a new read preference, new read
248
+ # concern or new write concern merged over the existing read preference /
249
+ # read concern / write concern.
209
250
  #
210
251
  # @example Get a collection with a changed read preference.
211
252
  # collection.with(read: { mode: :primary_preferred })
253
+
254
+ # @example Get a collection with a changed read concern.
255
+ # collection.with(read_concern: { level: :majority })
212
256
  #
213
257
  # @example Get a collection with a changed write concern.
214
258
  # collection.with(write_concern: { w: 3 })
215
-
259
+ #
216
260
  # @param [ Hash ] new_options The new options to use.
217
261
  #
262
+ # @option new_options [ Hash ] :read The read preference options.
263
+ # The hash may have the following items:
264
+ # - *:mode* -- read preference specified as a symbol; valid values are
265
+ # *:primary*, *:primary_preferred*, *:secondary*, *:secondary_preferred*
266
+ # and *:nearest*.
267
+ # - *:tag_sets* -- an array of hashes.
268
+ # - *:local_threshold*.
269
+ # @option new_options [ Hash ] :read_concern The read concern options hash,
270
+ # with the following optional keys:
271
+ # - *:level* -- the read preference level as a symbol; valid values
272
+ # are *:local*, *:majority*, and *:snapshot*
273
+ # @option new_options [ Hash ] :write Deprecated. Equivalent to :write_concern
274
+ # option.
275
+ # @option new_options [ Hash ] :write_concern The write concern options.
276
+ # Can be :w => Integer|String, :fsync => Boolean, :j => Boolean.
277
+ #
218
278
  # @return [ Mongo::Collection ] A new collection instance.
219
279
  #
220
280
  # @since 2.1.0
@@ -237,7 +297,7 @@ module Mongo
237
297
  # @example Is the collection capped?
238
298
  # collection.capped?
239
299
  #
240
- # @return [ true, false ] If the collection is capped.
300
+ # @return [ true | false ] If the collection is capped.
241
301
  #
242
302
  # @since 2.0.0
243
303
  def capped?
@@ -251,17 +311,48 @@ module Mongo
251
311
  #
252
312
  # @param [ Hash ] opts The options for the create operation.
253
313
  #
254
- # @option opts [ Session ] :session The session to use for the operation.
255
- # @option opts [ Hash ] :write_concern The write concern options.
256
- # @option opts [ Hash ] :time_series Create a time-series collection.
257
- # @option opts [ Integer ] :expire_after Number indicating
258
- # after how many seconds old time-series data should be deleted.
314
+ # @option opts [ true | false ] :capped Create a fixed-sized collection.
259
315
  # @option opts [ Hash ] :change_stream_pre_and_post_images Used to enable
260
316
  # pre- and post-images on the created collection.
317
+ # The hash may have the following items:
318
+ # - *:enabled* -- true or false.
319
+ # @option opts [ Hash ] :clustered_index Create a clustered index.
320
+ # This option specifies how this collection should be clustered on _id.
321
+ # The hash may have the following items:
322
+ # - *:key* -- The clustered index key field. Must be set to { _id: 1 }.
323
+ # - *:unique* -- Must be set to true. The collection will not accept
324
+ # inserted or updated documents where the clustered index key value
325
+ # matches an existing value in the index.
326
+ # - *:name* -- Optional. A name that uniquely identifies the clustered index.
327
+ # @option opts [ Hash ] :collation The collation to use.
261
328
  # @option opts [ Hash ] :encrypted_fields Hash describing encrypted fields
262
329
  # for queryable encryption.
330
+ # @option opts [ Integer ] :expire_after Number indicating
331
+ # after how many seconds old time-series data should be deleted.
332
+ # @option opts [ Integer ] :max The maximum number of documents in a
333
+ # capped collection. The size limit takes precedents over max.
334
+ # @option opts [ Array<Hash> ] :pipeline An array of pipeline stages.
335
+ # A view will be created by applying this pipeline to the view_on
336
+ # collection or view.
337
+ # @option opts [ Session ] :session The session to use for the operation.
338
+ # @option opts [ Integer ] :size The size of the capped collection.
339
+ # @option opts [ Hash ] :time_series Create a time-series collection.
340
+ # The hash may have the following items:
341
+ # - *:timeField* -- The name of the field which contains the date in each
342
+ # time series document.
343
+ # - *:metaField* -- The name of the field which contains metadata in each
344
+ # time series document.
345
+ # - *:granularity* -- Set the granularity to the value that is the closest
346
+ # match to the time span between consecutive incoming measurements.
347
+ # Possible values are "seconds" (default), "minutes", and "hours".
263
348
  # @option opts [ Hash ] :validator Hash describing document validation
264
349
  # options for the collection.
350
+ # @option opts [ String ] :view_on The name of the source collection or
351
+ # view from which to create a view.
352
+ # @option opts [ Hash ] :write Deprecated. Equivalent to :write_concern
353
+ # option.
354
+ # @option opts [ Hash ] :write_concern The write concern options.
355
+ # Can be :w => Integer|String, :fsync => Boolean, :j => Boolean.
265
356
  #
266
357
  # @return [ Result ] The result of the command.
267
358
  #
@@ -318,8 +409,10 @@ module Mongo
318
409
  #
319
410
  # @param [ Hash ] opts The options for the drop operation.
320
411
  #
321
- # @option options [ Session ] :session The session to use for the operation.
412
+ # @option opts [ Session ] :session The session to use for the operation.
322
413
  # @option opts [ Hash ] :write_concern The write concern options.
414
+ # @option opts [ Hash | nil ] :encrypted_fields Encrypted fields hash that
415
+ # was provided to `create` collection helper.
323
416
  #
324
417
  # @return [ Result ] The result of the command.
325
418
  #
@@ -356,27 +449,27 @@ module Mongo
356
449
  # @param [ Hash ] filter The filter to use in the find.
357
450
  # @param [ Hash ] options The options for the find.
358
451
  #
359
- # @option options [ true, false ] :allow_disk_use When set to true, the
452
+ # @option options [ true | false ] :allow_disk_use When set to true, the
360
453
  # server can write temporary data to disk while executing the find
361
454
  # operation. This option is only available on MongoDB server versions
362
455
  # 4.4 and newer.
363
- # @option options [ true, false ] :allow_partial_results Allows the query to get partial
456
+ # @option options [ true | false ] :allow_partial_results Allows the query to get partial
364
457
  # results if some shards are down.
365
458
  # @option options [ Integer ] :batch_size The number of documents returned in each batch
366
459
  # of results from MongoDB.
367
460
  # @option options [ Hash ] :collation The collation to use.
368
- # @option options [ Object ] :comment A user-provided
369
- # comment to attach to this command.
461
+ # @option options [ Object ] :comment A user-provided comment to attach to
462
+ # this command.
370
463
  # @option options [ :tailable, :tailable_await ] :cursor_type The type of cursor to use.
371
464
  # @option options [ Integer ] :limit The max number of docs to return from the query.
372
465
  # @option options [ Integer ] :max_time_ms
373
466
  # The maximum amount of time to allow the query to run, in milliseconds.
374
467
  # @option options [ Hash ] :modifiers A document containing meta-operators modifying the
375
468
  # output or behavior of a query.
376
- # @option options [ true, false ] :no_cursor_timeout The server normally times out idle
469
+ # @option options [ true | false ] :no_cursor_timeout The server normally times out idle
377
470
  # cursors after an inactivity period (10 minutes) to prevent excess memory use.
378
471
  # Set this option to prevent that.
379
- # @option options [ true, false ] :oplog_replay For internal replication
472
+ # @option options [ true | false ] :oplog_replay For internal replication
380
473
  # use only, applications should not set this option.
381
474
  # @option options [ Hash ] :projection The fields to include or exclude from each doc
382
475
  # in the result set.
@@ -402,11 +495,11 @@ module Mongo
402
495
  # @param [ Array<Hash> ] pipeline The aggregation pipeline.
403
496
  # @param [ Hash ] options The aggregation options.
404
497
  #
405
- # @option options [ true, false ] :allow_disk_use Set to true if disk
498
+ # @option options [ true | false ] :allow_disk_use Set to true if disk
406
499
  # usage is allowed during the aggregation.
407
500
  # @option options [ Integer ] :batch_size The number of documents to return
408
501
  # per batch.
409
- # @option options [ true, false ] :bypass_document_validation Whether or
502
+ # @option options [ true | false ] :bypass_document_validation Whether or
410
503
  # not to skip document level validation.
411
504
  # @option options [ Hash ] :collation The collation to use.
412
505
  # @option options [ Object ] :comment A user-provided
@@ -416,7 +509,7 @@ module Mongo
416
509
  # See the server documentation for details.
417
510
  # @option options [ Integer ] :max_time_ms The maximum amount of time in
418
511
  # milliseconds to allow the aggregation to run.
419
- # @option options [ true, false ] :use_cursor Indicates whether the command
512
+ # @option options [ true | false ] :use_cursor Indicates whether the command
420
513
  # will request that the server provide results using a cursor. Note that
421
514
  # as of server version 3.6, aggregations always provide results using a
422
515
  # cursor and this option is therefore not valid.
@@ -642,7 +735,13 @@ module Mongo
642
735
  # @param [ Hash ] document The document to insert.
643
736
  # @param [ Hash ] opts The insert options.
644
737
  #
738
+ # @option opts [ true | false ] :bypass_document_validation Whether or
739
+ # not to skip document level validation.
740
+ # @option opts [ Object ] :comment A user-provided comment to attach to
741
+ # this command.
645
742
  # @option opts [ Session ] :session The session to use for the operation.
743
+ # @option opts [ Hash ] :write_concern The write concern options.
744
+ # Can be :w => Integer, :fsync => Boolean, :j => Boolean.
646
745
  #
647
746
  # @return [ Result ] The database response wrapper.
648
747
  #
@@ -684,12 +783,18 @@ module Mongo
684
783
  # @example Insert documents into the collection.
685
784
  # collection.insert_many([{ name: 'test' }])
686
785
  #
687
- # @param [ Array<Hash> ] documents The documents to insert.
786
+ # @param [ Enumerable<Hash> ] documents The documents to insert.
688
787
  # @param [ Hash ] options The insert options.
689
788
  #
789
+ # @option options [ true | false ] :bypass_document_validation Whether or
790
+ # not to skip document level validation.
791
+ # @option options [ Object ] :comment A user-provided comment to attach to
792
+ # this command.
690
793
  # @option options [ true | false ] :ordered Whether the operations
691
794
  # should be executed in order.
692
795
  # @option options [ Session ] :session The session to use for the operation.
796
+ # @option options [ Hash ] :write_concern The write concern options.
797
+ # Can be :w => Integer, :fsync => Boolean, :j => Boolean.
693
798
  #
694
799
  # @return [ Result ] The database response wrapper.
695
800
  #
@@ -706,14 +811,14 @@ module Mongo
706
811
  # @example Execute a bulk write.
707
812
  # collection.bulk_write(operations, options)
708
813
  #
709
- # @param [ Array<Hash> ] requests The bulk write requests.
814
+ # @param [ Enumerable<Hash> ] requests The bulk write requests.
710
815
  # @param [ Hash ] options The options.
711
816
  #
712
- # @option options [ true, false ] :ordered Whether the operations
817
+ # @option options [ true | false ] :ordered Whether the operations
713
818
  # should be executed in order.
714
819
  # @option options [ Hash ] :write_concern The write concern options.
715
820
  # Can be :w => Integer, :fsync => Boolean, :j => Boolean.
716
- # @option options [ true, false ] :bypass_document_validation Whether or
821
+ # @option options [ true | false ] :bypass_document_validation Whether or
717
822
  # not to skip document level validation.
718
823
  # @option options [ Session ] :session The session to use for the set of operations.
719
824
  # @option options [ Hash ] :let Mapping of variables to use in the command.
@@ -802,9 +907,9 @@ module Mongo
802
907
  # @param [ Hash ] replacement The replacement document..
803
908
  # @param [ Hash ] options The options.
804
909
  #
805
- # @option options [ true, false ] :upsert Whether to upsert if the
910
+ # @option options [ true | false ] :upsert Whether to upsert if the
806
911
  # document doesn't exist.
807
- # @option options [ true, false ] :bypass_document_validation Whether or
912
+ # @option options [ true | false ] :bypass_document_validation Whether or
808
913
  # not to skip document level validation.
809
914
  # @option options [ Hash ] :collation The collation to use.
810
915
  # @option options [ Session ] :session The session to use.
@@ -829,9 +934,9 @@ module Mongo
829
934
  # @param [ Hash | Array<Hash> ] update The update document or pipeline.
830
935
  # @param [ Hash ] options The options.
831
936
  #
832
- # @option options [ true, false ] :upsert Whether to upsert if the
937
+ # @option options [ true | false ] :upsert Whether to upsert if the
833
938
  # document doesn't exist.
834
- # @option options [ true, false ] :bypass_document_validation Whether or
939
+ # @option options [ true | false ] :bypass_document_validation Whether or
835
940
  # not to skip document level validation.
836
941
  # @option options [ Hash ] :collation The collation to use.
837
942
  # @option options [ Array ] :array_filters A set of filters specifying to which array elements
@@ -858,9 +963,9 @@ module Mongo
858
963
  # @param [ Hash | Array<Hash> ] update The update document or pipeline.
859
964
  # @param [ Hash ] options The options.
860
965
  #
861
- # @option options [ true, false ] :upsert Whether to upsert if the
966
+ # @option options [ true | false ] :upsert Whether to upsert if the
862
967
  # document doesn't exist.
863
- # @option options [ true, false ] :bypass_document_validation Whether or
968
+ # @option options [ true | false ] :bypass_document_validation Whether or
864
969
  # not to skip document level validation.
865
970
  # @option options [ Hash ] :collation The collation to use.
866
971
  # @option options [ Array ] :array_filters A set of filters specifying to which array elements
@@ -927,8 +1032,8 @@ module Mongo
927
1032
  # @option options [ Hash ] :sort The key and direction pairs by which the result set
928
1033
  # will be sorted.
929
1034
  # @option options [ Symbol ] :return_document Either :before or :after.
930
- # @option options [ true, false ] :upsert Whether to upsert if the document doesn't exist.
931
- # @option options [ true, false ] :bypass_document_validation Whether or
1035
+ # @option options [ true | false ] :upsert Whether to upsert if the document doesn't exist.
1036
+ # @option options [ true | false ] :bypass_document_validation Whether or
932
1037
  # not to skip document level validation.
933
1038
  # @option options [ Hash ] :write_concern The write concern options.
934
1039
  # Defaults to the collection's write concern.
@@ -967,8 +1072,8 @@ module Mongo
967
1072
  # @option options [ Hash ] :sort The key and direction pairs by which the result set
968
1073
  # will be sorted.
969
1074
  # @option options [ Symbol ] :return_document Either :before or :after.
970
- # @option options [ true, false ] :upsert Whether to upsert if the document doesn't exist.
971
- # @option options [ true, false ] :bypass_document_validation Whether or
1075
+ # @option options [ true | false ] :upsert Whether to upsert if the document doesn't exist.
1076
+ # @option options [ true | false ] :bypass_document_validation Whether or
972
1077
  # not to skip document level validation.
973
1078
  # @option options [ Hash ] :write_concern The write concern options.
974
1079
  # Defaults to the collection's write concern.
@@ -81,6 +81,12 @@ module Mongo
81
81
  # and schemaMap, an error will be raised.
82
82
  # @option options [ Boolean | nil ] :bypass_query_analysis When true
83
83
  # disables automatic analysis of outgoing commands.
84
+ # @option options [ String | nil ] :crypt_shared_lib_path Path that should
85
+ # be the used to load the crypt shared library. Providing this option
86
+ # overrides default crypt shared library load paths for libmongocrypt.
87
+ # @option options [ Boolean | nil ] :crypt_shared_lib_required Whether
88
+ # crypt shared library is required. If 'true', an error will be raised
89
+ # if a crypt_shared library cannot be loaded by libmongocrypt.
84
90
  #
85
91
  # @raise [ ArgumentError ] If required options are missing or incorrectly
86
92
  # formatted.
@@ -95,17 +101,32 @@ module Mongo
95
101
  schema_map: @options[:schema_map],
96
102
  schema_map_path: @options[:schema_map_path],
97
103
  encrypted_fields_map: @options[:encrypted_fields_map],
98
- bypass_query_analysis: @options[:bypass_query_analysis]
104
+ bypass_query_analysis: @options[:bypass_query_analysis],
105
+ crypt_shared_lib_path: @options[:extra_options][:crypt_shared_lib_path],
106
+ crypt_shared_lib_required: @options[:extra_options][:crypt_shared_lib_required],
99
107
  )
100
108
 
101
- # Set server selection timeout to 1 to prevent the client waiting for a
102
- # long timeout before spawning mongocryptd
103
- @mongocryptd_client = Client.new(
104
- @options[:extra_options][:mongocryptd_uri],
105
- monitoring_io: @options[:client].options[:monitoring_io],
106
- server_selection_timeout: 10,
107
- database: @options[:client].options[:database]
109
+ @mongocryptd_options = @options[:extra_options].slice(
110
+ :mongocryptd_uri,
111
+ :mongocryptd_bypass_spawn,
112
+ :mongocryptd_spawn_path,
113
+ :mongocryptd_spawn_args
108
114
  )
115
+ @mongocryptd_options[:mongocryptd_bypass_spawn] = @options[:bypass_auto_encryption] ||
116
+ @options[:extra_options][:mongocryptd_bypass_spawn] ||
117
+ @crypt_handle.crypt_shared_lib_available? ||
118
+ @options[:extra_options][:crypt_shared_lib_required]
119
+
120
+ if !@options[:extra_options][:crypt_shared_lib_required]
121
+ # Set server selection timeout to 1 to prevent the client waiting for a
122
+ # long timeout before spawning mongocryptd
123
+ @mongocryptd_client = Client.new(
124
+ @options[:extra_options][:mongocryptd_uri],
125
+ monitoring_io: @options[:client].options[:monitoring_io],
126
+ server_selection_timeout: 10,
127
+ database: @options[:client].options[:database]
128
+ )
129
+ end
109
130
 
110
131
  begin
111
132
  @encryption_io = EncryptionIO.new(
@@ -118,7 +139,7 @@ module Mongo
118
139
  )
119
140
  rescue
120
141
  begin
121
- @mongocryptd_client.close
142
+ @mongocryptd_client&.close
122
143
  rescue => e
123
144
  log_warn("Error closing mongocryptd client in auto encrypter's constructor: #{e.class}: #{e}")
124
145
  # Drop this exception so that the original exception is raised
@@ -83,7 +83,7 @@ module Mongo
83
83
  # will cause a `LoadError`.
84
84
  #
85
85
  # @api private
86
- MIN_LIBMONGOCRYPT_VERSION = Gem::Version.new("1.5.0.alpha")
86
+ MIN_LIBMONGOCRYPT_VERSION = Gem::Version.new("1.5.2")
87
87
 
88
88
  # @!method self.mongocrypt_version(len)
89
89
  # @api private
@@ -107,6 +107,24 @@ module Mongo
107
107
  raise LoadError, "libmongocrypt version #{MIN_LIBMONGOCRYPT_VERSION} or above is required, " +
108
108
  "but version #{actual_version} was found."
109
109
  end
110
+ rescue ArgumentError => e
111
+ # Some lmc versions cannot be parsed with Gem::Version class,
112
+ # so we fall back to regex.
113
+ match = lmc_version.match(/\A(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)?(-[A-Za-z\+\d]+)?\z/)
114
+ if match.nil?
115
+ raise ArgumentError.new("Malformed version number string #{lmc_version}")
116
+ end
117
+ actual_version = Gem::Version.new(
118
+ [
119
+ match[:major],
120
+ match[:minor],
121
+ match[:patch]
122
+ ].join('.')
123
+ )
124
+ if actual_version < MIN_LIBMONGOCRYPT_VERSION
125
+ raise LoadError, "libmongocrypt version #{MIN_LIBMONGOCRYPT_VERSION} or above is required, " +
126
+ "but version #{actual_version} was found."
127
+ end
110
128
  end
111
129
 
112
130
  validate_version(mongocrypt_version(nil))
@@ -1385,6 +1403,80 @@ module Mongo
1385
1403
  end
1386
1404
  end
1387
1405
 
1406
+ # @!method self.mongocrypt_setopt_append_crypt_shared_lib_search_path(crypt, path)
1407
+ # @api private
1408
+ #
1409
+ # Append an additional search directory to the search path for loading
1410
+ # the crypt_shared dynamic library.
1411
+ #
1412
+ # @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object.
1413
+ # @param [ String ] path A path to search for the crypt shared library. If the leading element of
1414
+ # the path is the literal string "$ORIGIN", that substring will be replaced
1415
+ # with the directory path containing the executable libmongocrypt module. If
1416
+ # the path string is literal "$SYSTEM", then libmongocrypt will defer to the
1417
+ # system's library resolution mechanism to find the crypt_shared library.
1418
+ attach_function(
1419
+ :mongocrypt_setopt_append_crypt_shared_lib_search_path,
1420
+ [
1421
+ :pointer,
1422
+ :string,
1423
+ ],
1424
+ :void
1425
+ )
1426
+
1427
+ # Append an additional search directory to the search path for loading
1428
+ # the crypt_shared dynamic library.
1429
+ #
1430
+ # @param [ Mongo::Crypt::Handle ] handle
1431
+ # @param [ String ] path A search path for the crypt shared library.
1432
+ def self.setopt_append_crypt_shared_lib_search_path(handle, path)
1433
+ check_status(handle) do
1434
+ mongocrypt_setopt_append_crypt_shared_lib_search_path(handle.ref, path)
1435
+ end
1436
+ end
1437
+
1438
+ # @!method self.mongocrypt_setopt_set_crypt_shared_lib_path_override(crypt, path)
1439
+ # @api private
1440
+ #
1441
+ # Set a single override path for loading the crypt shared library.
1442
+ #
1443
+ # @param [ FFI::Pointer ] crypt A pointer to a mongocrypt_t object.
1444
+ # @param [ String ] path A path to crypt shared library file. If the leading element of
1445
+ # the path is the literal string "$ORIGIN", that substring will be replaced
1446
+ # with the directory path containing the executable libmongocrypt module.
1447
+ attach_function(
1448
+ :mongocrypt_setopt_set_crypt_shared_lib_path_override,
1449
+ [
1450
+ :pointer,
1451
+ :string,
1452
+ ],
1453
+ :void
1454
+ )
1455
+
1456
+ # Set a single override path for loading the crypt shared library.
1457
+ #
1458
+ # @param [ Mongo::Crypt::Handle ] handle
1459
+ # @param [ String ] path A path to crypt shared library file.
1460
+ def self.setopt_set_crypt_shared_lib_path_override(handle, path)
1461
+ check_status(handle) do
1462
+ mongocrypt_setopt_set_crypt_shared_lib_path_override(handle.ref, path)
1463
+ end
1464
+ end
1465
+
1466
+ # MONGOCRYPT_EXPORT
1467
+ # uint64_t
1468
+ # mongocrypt_crypt_shared_lib_version (const mongocrypt_t *crypt);
1469
+ attach_function(
1470
+ :mongocrypt_crypt_shared_lib_version,
1471
+ [ :pointer ],
1472
+ :uint64
1473
+ )
1474
+
1475
+ def self.crypt_shared_lib_version(handle)
1476
+ mongocrypt_crypt_shared_lib_version(handle.ref)
1477
+ end
1478
+
1479
+
1388
1480
  # @!method self.mongocrypt_ctx_setopt_query_type(ctx, mongocrypt_query_type)
1389
1481
  # @api private
1390
1482
  #
@@ -36,7 +36,11 @@ module Mongo
36
36
  # should be hashes of TLS connection options. The options are equivalent
37
37
  # to TLS connection options of Mongo::Client.
38
38
  def initialize(key_vault_client, key_vault_namespace, kms_providers, kms_tls_options)
39
- @crypt_handle = Handle.new(kms_providers, kms_tls_options)
39
+ @crypt_handle = Handle.new(
40
+ kms_providers,
41
+ kms_tls_options,
42
+ explicit_encryption_only: true
43
+ )
40
44
  @encryption_io = EncryptionIO.new(
41
45
  key_vault_client: key_vault_client,
42
46
  metadata_client: nil,