mongoid 8.0.5 → 8.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +3 -3
  4. data/README.md +3 -3
  5. data/Rakefile +0 -25
  6. data/lib/config/locales/en.yml +46 -14
  7. data/lib/mongoid/association/accessors.rb +2 -2
  8. data/lib/mongoid/association/builders.rb +1 -1
  9. data/lib/mongoid/association/embedded/batchable.rb +2 -2
  10. data/lib/mongoid/association/embedded/embedded_in/buildable.rb +2 -2
  11. data/lib/mongoid/association/embedded/embedded_in/proxy.rb +2 -1
  12. data/lib/mongoid/association/embedded/embeds_many/buildable.rb +3 -2
  13. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +6 -6
  14. data/lib/mongoid/association/embedded/embeds_one/buildable.rb +1 -1
  15. data/lib/mongoid/association/embedded/embeds_one/proxy.rb +1 -1
  16. data/lib/mongoid/association/nested/one.rb +40 -2
  17. data/lib/mongoid/association/proxy.rb +1 -1
  18. data/lib/mongoid/association/referenced/counter_cache.rb +2 -2
  19. data/lib/mongoid/association/referenced/has_and_belongs_to_many/proxy.rb +1 -1
  20. data/lib/mongoid/association/referenced/has_many/enumerable.rb +2 -2
  21. data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -3
  22. data/lib/mongoid/association/reflections.rb +2 -2
  23. data/lib/mongoid/atomic.rb +0 -7
  24. data/lib/mongoid/attributes/dynamic.rb +1 -1
  25. data/lib/mongoid/attributes/nested.rb +2 -2
  26. data/lib/mongoid/attributes/projector.rb +1 -1
  27. data/lib/mongoid/attributes/readonly.rb +1 -1
  28. data/lib/mongoid/attributes.rb +8 -2
  29. data/lib/mongoid/changeable.rb +107 -5
  30. data/lib/mongoid/clients/storage_options.rb +2 -5
  31. data/lib/mongoid/clients/validators/storage.rb +1 -13
  32. data/lib/mongoid/collection_configurable.rb +58 -0
  33. data/lib/mongoid/composable.rb +2 -0
  34. data/lib/mongoid/config/defaults.rb +60 -0
  35. data/lib/mongoid/config/validators/async_query_executor.rb +24 -0
  36. data/lib/mongoid/config/validators.rb +1 -0
  37. data/lib/mongoid/config.rb +101 -0
  38. data/lib/mongoid/contextual/atomic.rb +1 -1
  39. data/lib/mongoid/contextual/memory.rb +233 -33
  40. data/lib/mongoid/contextual/mongo/documents_loader.rb +177 -0
  41. data/lib/mongoid/contextual/mongo.rb +373 -113
  42. data/lib/mongoid/contextual/none.rb +162 -7
  43. data/lib/mongoid/contextual.rb +12 -0
  44. data/lib/mongoid/criteria/findable.rb +2 -2
  45. data/lib/mongoid/criteria/includable.rb +4 -3
  46. data/lib/mongoid/criteria/queryable/key.rb +1 -1
  47. data/lib/mongoid/criteria/queryable/mergeable.rb +1 -1
  48. data/lib/mongoid/criteria/queryable/optional.rb +8 -8
  49. data/lib/mongoid/criteria/queryable/selectable.rb +43 -12
  50. data/lib/mongoid/criteria.rb +6 -5
  51. data/lib/mongoid/deprecable.rb +1 -1
  52. data/lib/mongoid/errors/create_collection_failure.rb +33 -0
  53. data/lib/mongoid/errors/drop_collection_failure.rb +27 -0
  54. data/lib/mongoid/errors/immutable_attribute.rb +26 -0
  55. data/lib/mongoid/errors/invalid_async_query_executor.rb +25 -0
  56. data/lib/mongoid/errors/invalid_global_executor_concurrency.rb +22 -0
  57. data/lib/mongoid/errors/invalid_storage_parent.rb +2 -0
  58. data/lib/mongoid/errors.rb +4 -1
  59. data/lib/mongoid/extensions/object.rb +2 -2
  60. data/lib/mongoid/extensions/time.rb +2 -0
  61. data/lib/mongoid/fields/localized.rb +10 -0
  62. data/lib/mongoid/fields/standard.rb +10 -0
  63. data/lib/mongoid/fields.rb +69 -13
  64. data/lib/mongoid/findable.rb +27 -3
  65. data/lib/mongoid/interceptable.rb +7 -6
  66. data/lib/mongoid/matcher/eq_impl.rb +1 -1
  67. data/lib/mongoid/matcher/type.rb +1 -1
  68. data/lib/mongoid/persistable/creatable.rb +1 -0
  69. data/lib/mongoid/persistable/deletable.rb +1 -1
  70. data/lib/mongoid/persistable/savable.rb +13 -1
  71. data/lib/mongoid/persistable/unsettable.rb +2 -2
  72. data/lib/mongoid/persistable/updatable.rb +51 -1
  73. data/lib/mongoid/persistable/upsertable.rb +20 -1
  74. data/lib/mongoid/persistable.rb +3 -0
  75. data/lib/mongoid/query_cache.rb +5 -1
  76. data/lib/mongoid/railties/database.rake +7 -2
  77. data/lib/mongoid/reloadable.rb +5 -3
  78. data/lib/mongoid/stateful.rb +22 -1
  79. data/lib/mongoid/tasks/database.rake +12 -0
  80. data/lib/mongoid/tasks/database.rb +20 -0
  81. data/lib/mongoid/utils.rb +22 -0
  82. data/lib/mongoid/validatable/macros.rb +5 -5
  83. data/lib/mongoid/validatable.rb +4 -1
  84. data/lib/mongoid/version.rb +1 -1
  85. data/lib/mongoid/warnings.rb +17 -1
  86. data/lib/mongoid.rb +16 -3
  87. data/spec/integration/app_spec.rb +2 -2
  88. data/spec/integration/callbacks_models.rb +37 -0
  89. data/spec/integration/callbacks_spec.rb +134 -0
  90. data/spec/integration/discriminator_key_spec.rb +4 -5
  91. data/spec/integration/i18n_fallbacks_spec.rb +3 -2
  92. data/spec/mongoid/association/embedded/embedded_in/proxy_spec.rb +27 -0
  93. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +20 -25
  94. data/spec/mongoid/association/embedded/embeds_many_models.rb +1 -0
  95. data/spec/mongoid/association/embedded/embeds_one/proxy_spec.rb +15 -2
  96. data/spec/mongoid/association/referenced/belongs_to_spec.rb +2 -18
  97. data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +5 -27
  98. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +9 -50
  99. data/spec/mongoid/association/syncable_spec.rb +1 -1
  100. data/spec/mongoid/attributes_spec.rb +3 -6
  101. data/spec/mongoid/changeable_spec.rb +299 -24
  102. data/spec/mongoid/clients_spec.rb +122 -13
  103. data/spec/mongoid/collection_configurable_spec.rb +158 -0
  104. data/spec/mongoid/config/defaults_spec.rb +160 -0
  105. data/spec/mongoid/config_spec.rb +154 -18
  106. data/spec/mongoid/contextual/memory_spec.rb +332 -76
  107. data/spec/mongoid/contextual/mongo/documents_loader_spec.rb +187 -0
  108. data/spec/mongoid/contextual/mongo_spec.rb +995 -36
  109. data/spec/mongoid/contextual/none_spec.rb +49 -2
  110. data/spec/mongoid/copyable_spec.rb +3 -11
  111. data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +4 -10
  112. data/spec/mongoid/criteria/queryable/options_spec.rb +1 -1
  113. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +419 -0
  114. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -1
  115. data/spec/mongoid/criteria/queryable/selector_spec.rb +1 -1
  116. data/spec/mongoid/criteria_projection_spec.rb +1 -4
  117. data/spec/mongoid/criteria_spec.rb +5 -9
  118. data/spec/mongoid/errors/readonly_document_spec.rb +2 -2
  119. data/spec/mongoid/extensions/time_spec.rb +8 -43
  120. data/spec/mongoid/extensions/time_with_zone_spec.rb +7 -52
  121. data/spec/mongoid/fields/localized_spec.rb +46 -28
  122. data/spec/mongoid/fields_spec.rb +136 -34
  123. data/spec/mongoid/findable_spec.rb +391 -34
  124. data/spec/mongoid/indexable_spec.rb +16 -10
  125. data/spec/mongoid/interceptable_spec.rb +15 -3
  126. data/spec/mongoid/persistable/deletable_spec.rb +26 -6
  127. data/spec/mongoid/persistable/destroyable_spec.rb +26 -6
  128. data/spec/mongoid/persistable/incrementable_spec.rb +37 -0
  129. data/spec/mongoid/persistable/logical_spec.rb +37 -0
  130. data/spec/mongoid/persistable/poppable_spec.rb +36 -0
  131. data/spec/mongoid/persistable/pullable_spec.rb +72 -0
  132. data/spec/mongoid/persistable/pushable_spec.rb +72 -0
  133. data/spec/mongoid/persistable/renamable_spec.rb +36 -0
  134. data/spec/mongoid/persistable/savable_spec.rb +96 -0
  135. data/spec/mongoid/persistable/settable_spec.rb +37 -0
  136. data/spec/mongoid/persistable/unsettable_spec.rb +36 -0
  137. data/spec/mongoid/persistable/updatable_spec.rb +20 -28
  138. data/spec/mongoid/persistable/upsertable_spec.rb +80 -6
  139. data/spec/mongoid/persistence_context_spec.rb +7 -57
  140. data/spec/mongoid/query_cache_spec.rb +56 -61
  141. data/spec/mongoid/reloadable_spec.rb +24 -28
  142. data/spec/mongoid/scopable_spec.rb +70 -0
  143. data/spec/mongoid/serializable_spec.rb +9 -30
  144. data/spec/mongoid/stateful_spec.rb +122 -8
  145. data/spec/mongoid/tasks/database_rake_spec.rb +74 -0
  146. data/spec/mongoid/tasks/database_spec.rb +127 -0
  147. data/spec/mongoid/timestamps_spec.rb +9 -11
  148. data/spec/mongoid/touchable_spec.rb +277 -5
  149. data/spec/mongoid/touchable_spec_models.rb +3 -1
  150. data/spec/mongoid/traversable_spec.rb +9 -24
  151. data/spec/mongoid/validatable/uniqueness_spec.rb +2 -3
  152. data/spec/mongoid_spec.rb +36 -10
  153. data/spec/shared/lib/mrss/docker_runner.rb +7 -0
  154. data/spec/shared/lib/mrss/event_subscriber.rb +15 -5
  155. data/spec/shared/lib/mrss/lite_constraints.rb +10 -2
  156. data/spec/shared/lib/mrss/server_version_registry.rb +16 -23
  157. data/spec/shared/lib/mrss/utils.rb +28 -6
  158. data/spec/shared/share/Dockerfile.erb +36 -40
  159. data/spec/shared/shlib/server.sh +32 -8
  160. data/spec/shared/shlib/set_env.sh +4 -4
  161. data/spec/spec_helper.rb +5 -0
  162. data/spec/support/immutable_ids.rb +118 -0
  163. data/spec/support/macros.rb +47 -15
  164. data/spec/support/models/artist.rb +0 -1
  165. data/spec/support/models/band.rb +1 -0
  166. data/spec/support/models/book.rb +1 -0
  167. data/spec/support/models/building.rb +2 -0
  168. data/spec/support/models/cover.rb +10 -0
  169. data/spec/support/models/product.rb +1 -0
  170. data.tar.gz.sig +0 -0
  171. metadata +686 -650
  172. metadata.gz.sig +0 -0
  173. data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +0 -60
  174. data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +0 -60
@@ -68,9 +68,13 @@ module Mongoid
68
68
  # @example Move the changes to previous.
69
69
  # person.move_changes
70
70
  def move_changes
71
+ @changes_before_last_save = @previous_changes
71
72
  @previous_changes = changes
73
+ @attributes_before_last_save = @previous_attributes
72
74
  @previous_attributes = attributes.dup
73
- reset_atomic_updates!
75
+ Atomic::UPDATES.each do |update|
76
+ send(update).clear
77
+ end
74
78
  changed_attributes.clear
75
79
  end
76
80
 
@@ -131,6 +135,72 @@ module Mongoid
131
135
  mods
132
136
  end
133
137
 
138
+ # Returns the original value of an attribute before the last save.
139
+ #
140
+ # This method is useful in after callbacks to get the original value of
141
+ # an attribute before the save that triggered the callbacks to run.
142
+ #
143
+ # @param [ Symbol | String ] attr The name of the attribute.
144
+ #
145
+ # @return [ Object ] Value of the attribute before the last save.
146
+ def attribute_before_last_save(attr)
147
+ attr = database_field_name(attr)
148
+ attributes_before_last_save[attr]
149
+ end
150
+
151
+ # Returns the change to an attribute during the last save.
152
+ #
153
+ # @param [ Symbol | String ] attr The name of the attribute.
154
+ #
155
+ # @return [ Array<Object> | nil ] If the attribute was changed, returns
156
+ # an array containing the original value and the saved value, otherwise nil.
157
+ def saved_change_to_attribute(attr)
158
+ attr = database_field_name(attr)
159
+ previous_changes[attr]
160
+ end
161
+
162
+ # Returns whether this attribute changed during the last save.
163
+ #
164
+ # This method is useful in after callbacks, to see the change
165
+ # in an attribute during the save that triggered the callbacks to run.
166
+ #
167
+ # @param [ String ] attr The name of the attribute.
168
+ # @param **kwargs The optional keyword arguments.
169
+ #
170
+ # @option **kwargs [ Object ] :from The object the attribute was changed from.
171
+ # @option **kwargs [ Object ] :to The object the attribute was changed to.
172
+ #
173
+ # @return [ true | false ] Whether the attribute has changed during the last save.
174
+ def saved_change_to_attribute?(attr, **kwargs)
175
+ changes = saved_change_to_attribute(attr)
176
+ return false unless changes.is_a?(Array)
177
+ if kwargs.key?(:from) && kwargs.key?(:to)
178
+ changes.first == kwargs[:from] && changes.last == kwargs[:to]
179
+ elsif kwargs.key?(:from)
180
+ changes.first == kwargs[:from]
181
+ elsif kwargs.key?(:to)
182
+ changes.last == kwargs[:to]
183
+ else
184
+ true
185
+ end
186
+ end
187
+
188
+ # Returns whether this attribute change the next time we save.
189
+ #
190
+ # This method is useful in validations and before callbacks to determine
191
+ # if the next call to save will change a particular attribute.
192
+ #
193
+ # @param [ String ] attr The name of the attribute.
194
+ # @param **kwargs The optional keyword arguments.
195
+ #
196
+ # @option **kwargs [ Object ] :from The object the attribute was changed from.
197
+ # @option **kwargs [ Object ] :to The object the attribute was changed to.
198
+ #
199
+ # @return [ true | false ] Whether the attribute change the next time we save.
200
+ def will_save_change_to_attribute?(attr, **kwargs)
201
+ attribute_changed?(attr, **kwargs)
202
+ end
203
+
134
204
  private
135
205
 
136
206
  # Get attributes of the document before the document was saved.
@@ -140,6 +210,14 @@ module Mongoid
140
210
  @previous_attributes ||= {}
141
211
  end
142
212
 
213
+ def changes_before_last_save
214
+ @changes_before_last_save ||= {}
215
+ end
216
+
217
+ def attributes_before_last_save
218
+ @attributes_before_last_save ||= {}
219
+ end
220
+
143
221
  # Get the old and new value for the provided attribute.
144
222
  #
145
223
  # @example Get the attribute change.
@@ -159,12 +237,24 @@ module Mongoid
159
237
  # model.attribute_changed?("name")
160
238
  #
161
239
  # @param [ String ] attr The name of the attribute.
240
+ # @param **kwargs The optional keyword arguments.
241
+ #
242
+ # @option **kwargs [ Object ] :from The object the attribute was changed from.
243
+ # @option **kwargs [ Object ] :to The object the attribute was changed to.
162
244
  #
163
245
  # @return [ true | false ] Whether the attribute has changed.
164
- def attribute_changed?(attr)
246
+ def attribute_changed?(attr, **kwargs)
165
247
  attr = database_field_name(attr)
166
248
  return false unless changed_attributes.key?(attr)
167
- changed_attributes[attr] != attributes[attr]
249
+ return false if changed_attributes[attr] == attributes[attr]
250
+ if kwargs.key?(:from)
251
+ return false if changed_attributes[attr] != kwargs[:from]
252
+ end
253
+ if kwargs.key?(:to)
254
+ return false if attributes[attr] != kwargs[:to]
255
+ end
256
+
257
+ true
168
258
  end
169
259
 
170
260
  # Get whether or not the field has a different value from the default.
@@ -300,8 +390,11 @@ module Mongoid
300
390
  # @param [ String ] meth The name of the accessor.
301
391
  def create_dirty_change_check(name, meth)
302
392
  generated_methods.module_eval do
303
- re_define_method("#{meth}_changed?") do
304
- attribute_changed?(name)
393
+ re_define_method("#{meth}_changed?") do |**kwargs|
394
+ attribute_changed?(name, **kwargs)
395
+ end
396
+ re_define_method("will_save_change_to_#{meth}?") do |**kwargs|
397
+ will_save_change_to_attribute?(name, **kwargs)
305
398
  end
306
399
  end
307
400
  end
@@ -336,6 +429,15 @@ module Mongoid
336
429
  re_define_method("#{meth}_previously_was") do
337
430
  attribute_previously_was(name)
338
431
  end
432
+ re_define_method("#{meth}_before_last_save") do
433
+ attribute_before_last_save(name)
434
+ end
435
+ re_define_method("saved_change_to_#{meth}") do
436
+ saved_change_to_attribute(name)
437
+ end
438
+ re_define_method("saved_change_to_#{meth}?") do |**kwargs|
439
+ saved_change_to_attribute?(name, **kwargs)
440
+ end
339
441
  end
340
442
  end
341
443
 
@@ -6,10 +6,7 @@ module Mongoid
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  included do
9
-
10
- cattr_accessor :storage_options, instance_writer: false do
11
- storage_options_defaults
12
- end
9
+ class_attribute :storage_options, instance_writer: false, default: storage_options_defaults
13
10
  end
14
11
 
15
12
  module ClassMethods
@@ -49,7 +46,7 @@ module Mongoid
49
46
  # @return [ Class ] The model class.
50
47
  def store_in(options)
51
48
  Validators::Storage.validate(self, options)
52
- storage_options.merge!(options)
49
+ self.storage_options = self.storage_options.merge(options)
53
50
  end
54
51
 
55
52
  # Reset the store_in options
@@ -9,7 +9,7 @@ module Mongoid
9
9
  extend self
10
10
 
11
11
  # The valid options for storage.
12
- VALID_OPTIONS = [ :collection, :database, :client ].freeze
12
+ VALID_OPTIONS = [ :collection, :collection_options, :database, :client ].freeze
13
13
 
14
14
  # Validate the options provided to :store_in.
15
15
  #
@@ -20,21 +20,9 @@ module Mongoid
20
20
  # @param [ Hash | String | Symbol ] options The provided options.
21
21
  def validate(klass, options)
22
22
  valid_keys?(options) or raise Errors::InvalidStorageOptions.new(klass, options)
23
- valid_parent?(klass) or raise Errors::InvalidStorageParent.new(klass)
24
23
  end
25
24
 
26
25
  private
27
- # Determine if the current klass is valid to change store_in
28
- # options
29
- #
30
- # @api private
31
- #
32
- # @param [ Class ] klass
33
- #
34
- # @return [ true | false ] If the class is valid.
35
- def valid_parent?(klass)
36
- !klass.superclass.include?(Mongoid::Document)
37
- end
38
26
 
39
27
  # Determine if all keys in the options hash are valid.
40
28
  #
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongoid
4
+
5
+ # Encapsulates behavior around defining collections.
6
+ module CollectionConfigurable
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ # Create the collection for the called upon Mongoid model.
11
+ #
12
+ # This method does not re-create existing collections.
13
+ #
14
+ # If the document includes `store_in` macro with `collection_options` key,
15
+ # these options are used when creating the collection.
16
+ #
17
+ # @param [ true | false ] force If true, the method will drop existing
18
+ # collections before creating new ones. If false, the method will create
19
+ # only new collection (that do not exist in the database).
20
+ #
21
+ # @raise [ Errors::CreateCollectionFailure ] If collection creation failed.
22
+ # @raise [ Errors::DropCollectionFailure ] If an attempt to drop collection failed.
23
+ def create_collection(force: false)
24
+ if collection_name.empty?
25
+ # This is most probably an anonymous class, we ignore them.
26
+ return
27
+ end
28
+ if collection_name.match(/^system\./)
29
+ # We do not do anything with system collections.
30
+ return
31
+ end
32
+ if force
33
+ collection.drop
34
+ end
35
+ if coll_options = collection.database.list_collections(filter: { name: collection_name.to_s }).first
36
+ if force
37
+ raise Errors::DropCollectionFailure.new(collection_name)
38
+ else
39
+ logger.debug(
40
+ "MONGOID: Collection '#{collection_name}' already exists " +
41
+ "in database '#{database_name}' with options '#{coll_options}'."
42
+ )
43
+ end
44
+ else
45
+ begin
46
+ collection.database[collection_name, storage_options.fetch(:collection_options, {})].create
47
+ rescue Mongo::Error::OperationFailure => e
48
+ raise Errors::CreateCollectionFailure.new(
49
+ collection_name,
50
+ storage_options[:collection_options],
51
+ e
52
+ )
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require "mongoid/changeable"
4
+ require "mongoid/collection_configurable"
4
5
  require "mongoid/findable"
5
6
  require "mongoid/indexable"
6
7
  require "mongoid/inspectable"
@@ -36,6 +37,7 @@ module Mongoid
36
37
  include Atomic
37
38
  include Changeable
38
39
  include Clients
40
+ include CollectionConfigurable
39
41
  include Attributes
40
42
  include Evolvable
41
43
  include Fields
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongoid
4
+ module Config
5
+
6
+ # Encapsulates logic for loading defaults.
7
+ module Defaults
8
+
9
+ # Load the defaults for the feature flags in the given Mongoid version.
10
+ # Note that this method will load the *new* functionality introduced in
11
+ # the given Mongoid version.
12
+ #
13
+ # @param [ String | Float ] The version number as X.y.
14
+ #
15
+ # raises [ ArgumentError ] if an invalid version is given.
16
+ def load_defaults(version)
17
+ # Note that for 7.x, since all of the feature flag defaults have been
18
+ # flipped to the new functionality, all of the settings for those
19
+ # versions are to give old functionality. Because of this, it is
20
+ # possible to recurse to later version to get all of the options to
21
+ # turn off. Note that this won't be true when adding feature flags to
22
+ # 9.x, since the default will be the old functionality until the next
23
+ # major version is released. More likely, the recursion will have to go
24
+ # in the other direction (towards earlier versions).
25
+
26
+ case version.to_s
27
+ when "7.3"
28
+ # flags introduced in 7.4 - old functionality
29
+ self.broken_aggregables = true
30
+ self.broken_alias_handling = true
31
+ self.broken_and = true
32
+ self.broken_scoping = true
33
+ self.broken_updates = true
34
+ self.compare_time_by_ms = false
35
+ self.legacy_pluck_distinct = true
36
+ self.legacy_triple_equals = true
37
+ self.object_id_as_json_oid = true
38
+
39
+ load_defaults "7.4"
40
+ when "7.4"
41
+ # flags introduced in 7.5 - old functionality
42
+ self.legacy_attributes = true
43
+ self.overwrite_chained_operators = true
44
+
45
+ load_defaults "7.5"
46
+ when "7.5"
47
+ # flags introduced in 8.0 - old functionality
48
+ self.map_big_decimal_to_decimal128 = false
49
+ when "8.0"
50
+ # All flag defaults currently reflect 8.0 behavior.
51
+ when "8.1"
52
+ # flags introduced in 8.1 - new functionality
53
+ self.legacy_readonly = false
54
+ else
55
+ raise ArgumentError, "Unknown version: #{version}"
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Mongoid
4
+ module Config
5
+ module Validators
6
+
7
+ # Validator for async query executor configuration.
8
+ #
9
+ # @api private
10
+ module AsyncQueryExecutor
11
+ extend self
12
+
13
+
14
+ def validate(options)
15
+ if options.key?(:async_query_executor)
16
+ if options[:async_query_executor].to_sym == :immediate && !options[:global_executor_concurrency].nil?
17
+ raise Errors::InvalidGlobalExecutorConcurrency
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "mongoid/config/validators/async_query_executor"
3
4
  require "mongoid/config/validators/option"
4
5
  require "mongoid/config/validators/client"
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "mongoid/config/defaults"
3
4
  require "mongoid/config/environment"
4
5
  require "mongoid/config/options"
5
6
  require "mongoid/config/validators"
@@ -11,6 +12,7 @@ module Mongoid
11
12
  module Config
12
13
  extend Forwardable
13
14
  extend Options
15
+ extend Defaults
14
16
  extend self
15
17
 
16
18
  def_delegators ::Mongoid, :logger, :logger=
@@ -70,6 +72,7 @@ module Mongoid
70
72
 
71
73
  # Use ActiveSupport's time zone in time operations instead of the
72
74
  # Ruby default time zone.
75
+ # @deprecated
73
76
  option :use_activesupport_time_zone, default: true
74
77
 
75
78
  # Return stored times as UTC.
@@ -125,6 +128,53 @@ module Mongoid
125
128
  # always return a Hash.
126
129
  option :legacy_attributes, default: false
127
130
 
131
+ # Sets the async_query_executor for the application. By default the thread pool executor
132
+ # is set to `:immediate. Options are:
133
+ #
134
+ # - :immediate - Initializes a single +Concurrent::ImmediateExecutor+
135
+ # - :global_thread_pool - Initializes a single +Concurrent::ThreadPoolExecutor+
136
+ # that uses the +async_query_concurrency+ for the +max_threads+ value.
137
+ option :async_query_executor, default: :immediate
138
+
139
+ # Defines how many asynchronous queries can be executed concurrently.
140
+ # This option should be set only if `async_query_executor` is set
141
+ # to `:global_thread_pool`.
142
+ option :global_executor_concurrency, default: nil
143
+
144
+ # When this flag is false, a document will become read-only only once the
145
+ # #readonly! method is called, and an error will be raised on attempting
146
+ # to save or update such documents, instead of just on delete. When this
147
+ # flag is true, a document is only read-only if it has been projected
148
+ # using #only or #without, and read-only documents will not be
149
+ # deletable/destroyable, but they will be savable/updatable.
150
+ # When this feature flag is turned on, the read-only state will be reset on
151
+ # reload, but when it is turned off, it won't be.
152
+ option :legacy_readonly, default: true
153
+
154
+ # When this flag is true, any attempt to change the _id of a persisted
155
+ # document will raise an exception (`Errors::ImmutableAttribute`).
156
+ # This will be the default in 9.0. When this flag is false (the default
157
+ # in 8.x), changing the _id of a persisted document might be ignored,
158
+ # or it might work, depending on the situation.
159
+ option :immutable_ids, default: false
160
+
161
+ # When this flag is true, callbacks for every embedded document will be
162
+ # called only once, even if the embedded document is embedded in multiple
163
+ # documents in the root document's dependencies graph.
164
+ # This will be the default in 9.0. Setting this flag to false restores the
165
+ # pre-9.0 behavior, where callbacks are called for every occurrence of an
166
+ # embedded document. The pre-9.0 behavior leads to a problem that for multi
167
+ # level nested documents callbacks are called multiple times.
168
+ # See https://jira.mongodb.org/browse/MONGOID-5542
169
+ option :prevent_multiple_calls_of_embedded_callbacks, default: false
170
+
171
+ # Returns the Config singleton, for use in the configure DSL.
172
+ #
173
+ # @return [ self ] The Config singleton.
174
+ def config
175
+ self
176
+ end
177
+
128
178
  # Has Mongoid been configured? This is checking that at least a valid
129
179
  # client config exists.
130
180
  #
@@ -206,6 +256,17 @@ module Mongoid
206
256
  end
207
257
  end
208
258
 
259
+ # Deregister a model in the application with Mongoid.
260
+ #
261
+ # @param [ Class ] klass The model to deregister.
262
+ #
263
+ # @api private
264
+ def deregister_model(klass)
265
+ LOCK.synchronize do
266
+ models.delete(klass)
267
+ end
268
+ end
269
+
209
270
  # From a hash of settings, load all the configuration.
210
271
  #
211
272
  # @example Load the configuration.
@@ -278,6 +339,7 @@ module Mongoid
278
339
  # @param [ Hash ] options The configuration options.
279
340
  def options=(options)
280
341
  if options
342
+ Validators::AsyncQueryExecutor.validate(options)
281
343
  options.each_pair do |option, value|
282
344
  Validators::Option.validate(option)
283
345
  send("#{option}=", value)
@@ -345,5 +407,44 @@ module Mongoid
345
407
  client
346
408
  end
347
409
  end
410
+
411
+ module DeprecatedOptions
412
+ OPTIONS = %i[ use_activesupport_time_zone
413
+ broken_aggregables
414
+ broken_alias_handling
415
+ broken_and
416
+ broken_scoping
417
+ broken_updates
418
+ compare_time_by_ms
419
+ legacy_attributes
420
+ legacy_pluck_distinct
421
+ legacy_triple_equals
422
+ object_id_as_json_oid
423
+ overwrite_chained_operators ]
424
+
425
+ if RUBY_VERSION < '3.0'
426
+ def self.prepended(klass)
427
+ klass.class_eval do
428
+ OPTIONS.each do |option|
429
+ alias_method :"#{option}_without_deprecation=", :"#{option}="
430
+
431
+ define_method(:"#{option}=") do |value|
432
+ Mongoid::Warnings.send(:"warn_#{option}_deprecated")
433
+ send(:"#{option}_without_deprecation=", value)
434
+ end
435
+ end
436
+ end
437
+ end
438
+ else
439
+ OPTIONS.each do |option|
440
+ define_method(:"#{option}=") do |value|
441
+ Mongoid::Warnings.send(:"warn_#{option}_deprecated")
442
+ super(value)
443
+ end
444
+ end
445
+ end
446
+ end
447
+
448
+ prepend DeprecatedOptions
348
449
  end
349
450
  end
@@ -150,7 +150,7 @@ module Mongoid
150
150
  # @example Unset the field on the matches.
151
151
  # context.unset(:name)
152
152
  #
153
- # @param [ String | Symbol | Array<String | Symbol> | Hash ] args
153
+ # @param [ [ String | Symbol | Array<String | Symbol> | Hash ]... ] *args
154
154
  # The name(s) of the field(s) to unset.
155
155
  # If a Hash is specified, its keys will be used irrespective of what
156
156
  # each key's value is, even if the value is nil or false.