mongo 2.18.0 → 2.18.2

Sign up to get free protection for your applications and to get access to all the features.
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,