mongoid 7.2.6 → 7.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/README.md +1 -1
  4. data/Rakefile +16 -0
  5. data/lib/config/locales/en.yml +2 -15
  6. data/lib/mongoid/association/accessors.rb +1 -1
  7. data/lib/mongoid/association/constrainable.rb +1 -1
  8. data/lib/mongoid/association/depending.rb +4 -4
  9. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  10. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  11. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +11 -4
  12. data/lib/mongoid/association/nested/many.rb +1 -1
  13. data/lib/mongoid/association/nested/one.rb +4 -2
  14. data/lib/mongoid/association/proxy.rb +7 -2
  15. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  16. data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
  17. data/lib/mongoid/association/referenced/has_many/proxy.rb +3 -3
  18. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  19. data/lib/mongoid/association/relatable.rb +0 -2
  20. data/lib/mongoid/attributes/projector.rb +120 -0
  21. data/lib/mongoid/attributes.rb +24 -13
  22. data/lib/mongoid/cacheable.rb +2 -2
  23. data/lib/mongoid/clients/factory.rb +22 -8
  24. data/lib/mongoid/clients.rb +1 -1
  25. data/lib/mongoid/config/environment.rb +1 -9
  26. data/lib/mongoid/config.rb +19 -2
  27. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  28. data/lib/mongoid/contextual/atomic.rb +2 -7
  29. data/lib/mongoid/contextual/none.rb +0 -3
  30. data/lib/mongoid/copyable.rb +1 -1
  31. data/lib/mongoid/criteria/findable.rb +1 -1
  32. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  33. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  34. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  35. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  36. data/lib/mongoid/criteria/queryable/selectable.rb +10 -10
  37. data/lib/mongoid/criteria/queryable/storable.rb +4 -4
  38. data/lib/mongoid/criteria.rb +5 -6
  39. data/lib/mongoid/document.rb +3 -18
  40. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  41. data/lib/mongoid/errors/mongoid_error.rb +1 -1
  42. data/lib/mongoid/errors.rb +0 -2
  43. data/lib/mongoid/evolvable.rb +1 -1
  44. data/lib/mongoid/extensions/boolean.rb +1 -2
  45. data/lib/mongoid/extensions/false_class.rb +1 -1
  46. data/lib/mongoid/extensions/hash.rb +2 -2
  47. data/lib/mongoid/extensions/true_class.rb +1 -1
  48. data/lib/mongoid/fields.rb +43 -5
  49. data/lib/mongoid/inspectable.rb +1 -1
  50. data/lib/mongoid/interceptable.rb +1 -1
  51. data/lib/mongoid/matcher/bits.rb +41 -0
  52. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  53. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  54. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  55. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  56. data/lib/mongoid/matcher/expression.rb +4 -0
  57. data/lib/mongoid/matcher/field_operator.rb +6 -0
  58. data/lib/mongoid/matcher/mod.rb +17 -0
  59. data/lib/mongoid/matcher/type.rb +99 -0
  60. data/lib/mongoid/matcher.rb +7 -0
  61. data/lib/mongoid/persistable/deletable.rb +1 -2
  62. data/lib/mongoid/persistable/destroyable.rb +8 -2
  63. data/lib/mongoid/persistable/updatable.rb +27 -2
  64. data/lib/mongoid/persistence_context.rb +1 -3
  65. data/lib/mongoid/query_cache.rb +36 -40
  66. data/lib/mongoid/selectable.rb +5 -7
  67. data/lib/mongoid/shardable.rb +21 -5
  68. data/lib/mongoid/tasks/database.rb +1 -1
  69. data/lib/mongoid/touchable.rb +23 -4
  70. data/lib/mongoid/validatable/associated.rb +1 -1
  71. data/lib/mongoid/validatable/presence.rb +3 -3
  72. data/lib/mongoid/validatable/uniqueness.rb +1 -1
  73. data/lib/mongoid/version.rb +1 -1
  74. data/lib/mongoid.rb +0 -1
  75. data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
  76. data/spec/integration/app_spec.rb +0 -3
  77. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  78. data/spec/integration/associations/has_one_spec.rb +48 -0
  79. data/spec/integration/criteria/date_field_spec.rb +1 -1
  80. data/spec/integration/document_spec.rb +9 -0
  81. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  82. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  83. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  84. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  85. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  86. data/spec/integration/matcher_operator_data/in.yml +16 -0
  87. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  88. data/spec/integration/matcher_operator_data/type.yml +70 -0
  89. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  90. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  91. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  92. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  93. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  94. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  95. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  96. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  97. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  98. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  99. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  100. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  101. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  102. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  103. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  104. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  105. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  106. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  107. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  108. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  109. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  110. data/spec/integration/stringified_symbol_field_spec.rb +2 -2
  111. data/spec/lite_spec_helper.rb +2 -0
  112. data/spec/mongoid/association/depending_spec.rb +391 -352
  113. data/spec/mongoid/association/embedded/embeds_many/proxy_spec.rb +4 -17
  114. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  115. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -25
  116. data/spec/mongoid/association/referenced/belongs_to_query_spec.rb +0 -20
  117. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  118. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  119. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
  120. data/spec/mongoid/association/referenced/has_many_models.rb +0 -17
  121. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  122. data/spec/mongoid/atomic/paths_spec.rb +64 -12
  123. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  124. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  125. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  126. data/spec/mongoid/attributes_spec.rb +98 -6
  127. data/spec/mongoid/clients/factory_spec.rb +51 -9
  128. data/spec/mongoid/clients/options_spec.rb +3 -11
  129. data/spec/mongoid/config/environment_spec.rb +8 -86
  130. data/spec/mongoid/config_spec.rb +32 -0
  131. data/spec/mongoid/contextual/atomic_spec.rb +25 -64
  132. data/spec/mongoid/contextual/geo_near_spec.rb +1 -1
  133. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  134. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  135. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  136. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  137. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  138. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
  139. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  140. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  141. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  142. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  143. data/spec/mongoid/criteria_spec.rb +0 -279
  144. data/spec/mongoid/document_query_spec.rb +0 -51
  145. data/spec/mongoid/document_spec.rb +14 -34
  146. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  147. data/spec/mongoid/errors/mongoid_error_spec.rb +8 -20
  148. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  149. data/spec/mongoid/extensions/string_spec.rb +5 -5
  150. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  151. data/spec/mongoid/fields/localized_spec.rb +4 -4
  152. data/spec/mongoid/fields_spec.rb +4 -4
  153. data/spec/mongoid/inspectable_spec.rb +12 -4
  154. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  155. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  156. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  157. data/spec/mongoid/persistable/updatable_spec.rb +0 -2
  158. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  159. data/spec/mongoid/persistable_spec.rb +2 -2
  160. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  161. data/spec/mongoid/query_cache_spec.rb +0 -24
  162. data/spec/mongoid/reloadable_spec.rb +18 -1
  163. data/spec/mongoid/shardable_spec.rb +44 -0
  164. data/spec/mongoid/touchable_spec.rb +104 -16
  165. data/spec/mongoid/touchable_spec_models.rb +52 -0
  166. data/spec/mongoid/validatable_spec.rb +1 -1
  167. data/spec/shared/lib/mrss/cluster_config.rb +3 -8
  168. data/spec/shared/lib/mrss/constraints.rb +10 -41
  169. data/spec/shared/lib/mrss/docker_runner.rb +1 -7
  170. data/spec/shared/lib/mrss/server_version_registry.rb +12 -17
  171. data/spec/shared/lib/mrss/spec_organizer.rb +1 -18
  172. data/spec/shared/share/Dockerfile.erb +33 -125
  173. data/spec/shared/shlib/server.sh +23 -100
  174. data/spec/shared/shlib/set_env.sh +1 -4
  175. data/spec/spec_helper.rb +7 -3
  176. data/spec/support/client_registry.rb +9 -0
  177. data/spec/support/models/address.rb +0 -4
  178. data/spec/support/models/bolt.rb +8 -0
  179. data/spec/support/models/hole.rb +13 -0
  180. data/spec/support/models/mop.rb +0 -1
  181. data/spec/support/models/nut.rb +8 -0
  182. data/spec/support/models/person.rb +6 -9
  183. data/spec/support/models/sealer.rb +8 -0
  184. data/spec/support/models/shirt.rb +12 -0
  185. data/spec/support/models/spacer.rb +8 -0
  186. data/spec/support/models/threadlocker.rb +8 -0
  187. data/spec/support/models/washer.rb +8 -0
  188. data.tar.gz.sig +0 -0
  189. metadata +609 -545
  190. metadata.gz.sig +0 -0
  191. data/lib/mongoid/errors/empty_config_file.rb +0 -26
  192. data/lib/mongoid/errors/invalid_config_file.rb +0 -26
  193. data/spec/integration/contextual/empty_spec.rb +0 -142
  194. data/spec/mongoid/errors/invalid_config_file_spec.rb +0 -32
  195. data/spec/shared/bin/s3-copy +0 -45
  196. data/spec/shared/bin/s3-upload +0 -69
  197. data/spec/shared/lib/mrss/event_subscriber.rb +0 -200
  198. data/spec/shared/share/haproxy-1.conf +0 -16
  199. data/spec/shared/share/haproxy-2.conf +0 -17
  200. data/spec/support/cluster_config.rb +0 -158
@@ -195,11 +195,11 @@ module Mongoid
195
195
  end
196
196
 
197
197
  typed_override(criterion, "$exists") do |value|
198
- ::Boolean.evolve(value)
198
+ Mongoid::Boolean.evolve(value)
199
199
  end
200
200
  end
201
201
  key :exists, :override, "$exists" do |value|
202
- ::Boolean.evolve(value)
202
+ Mongoid::Boolean.evolve(value)
203
203
  end
204
204
 
205
205
  # Add a $geoIntersects or $geoWithin selection. Symbol operators must
@@ -597,7 +597,7 @@ module Mongoid
597
597
  end
598
598
  _mongoid_expand_keys(new_s).each do |k, v|
599
599
  k = k.to_s
600
- if c.selector[k] || k.start_with?('$')
600
+ if c.selector[k] || k[0] == ?$
601
601
  c = c.send(:__multi__, [{'$nor' => [{k => v}]}], '$and')
602
602
  else
603
603
  if v.is_a?(Hash)
@@ -882,19 +882,19 @@ module Mongoid
882
882
  if criterion.nil?
883
883
  raise ArgumentError, 'Criterion cannot be nil here'
884
884
  end
885
+ unless Hash === criterion
886
+ raise Errors::InvalidQuery, "Expression must be a Hash: #{Errors::InvalidQuery.truncate_expr(criterion)}"
887
+ end
885
888
 
889
+ normalized = _mongoid_expand_keys(criterion)
886
890
  clone.tap do |query|
887
- unless Hash === criterion
888
- raise Errors::InvalidQuery, "Expression must be a Hash: #{Errors::InvalidQuery.truncate_expr(criterion)}"
889
- end
890
- criterion.each do |field, value|
891
+ normalized.each do |field, value|
891
892
  field_s = field.to_s
892
- if field_s.start_with?('$')
893
+ if field_s[0] == ?$
893
894
  # Query expression-level operator, like $and or $where
894
895
  query.add_operator_expression(field_s, value)
895
896
  else
896
- exp_field, exp_value = expand_one_condition(field, value)
897
- query.add_field_expression(exp_field, exp_value)
897
+ query.add_field_expression(field, value)
898
898
  end
899
899
  end
900
900
  query.reset_strategies!
@@ -38,7 +38,7 @@ module Mongoid
38
38
  raise ArgumentError, "Field must be a string: #{field}"
39
39
  end
40
40
 
41
- if field.start_with?('$')
41
+ if field[0] == ?$
42
42
  raise ArgumentError, "Field cannot be an operator (i.e. begin with $): #{field}"
43
43
  end
44
44
 
@@ -48,7 +48,7 @@ module Mongoid
48
48
  if value.is_a?(Hash) && selector[field].is_a?(Hash) &&
49
49
  value.keys.all? { |key|
50
50
  key_s = key.to_s
51
- key_s.start_with?('$') && !selector[field].key?(key_s)
51
+ key_s[0] == ?$ && !selector[field].key?(key_s)
52
52
  }
53
53
  then
54
54
  # Multiple operators can be combined on the same field by
@@ -185,7 +185,7 @@ module Mongoid
185
185
  raise ArgumentError, "Operator must be a string: #{operator}"
186
186
  end
187
187
 
188
- unless operator.start_with?('$')
188
+ unless operator[0] == ?$
189
189
  raise ArgumentError, "Operator must begin with $: #{operator}"
190
190
  end
191
191
 
@@ -220,7 +220,7 @@ module Mongoid
220
220
  raise ArgumentError, "Field must be a string: #{field}"
221
221
  end
222
222
 
223
- if field.start_with?('$')
223
+ if field[0] == ?$
224
224
  add_operator_expression(field, value)
225
225
  else
226
226
  add_field_expression(field, value)
@@ -336,16 +336,15 @@ module Mongoid
336
336
  #
337
337
  # @since 1.0.0
338
338
  def only(*args)
339
- return clone if args.flatten.empty?
340
339
  args = args.flatten
340
+ return clone if args.empty?
341
341
  if (args & Fields::IDS).empty?
342
342
  args.unshift(:_id)
343
343
  end
344
344
  if klass.hereditary?
345
- super(*args.push(klass.discriminator_key.to_sym))
346
- else
347
- super(*args)
345
+ args.push(klass.discriminator_key.to_sym)
348
346
  end
347
+ super(*args)
349
348
  end
350
349
 
351
350
  # Set the read preference for the criteria.
@@ -375,7 +374,7 @@ module Mongoid
375
374
  #
376
375
  # @since 4.0.3
377
376
  def without(*args)
378
- args -= Fields::IDS
377
+ args -= id_fields
379
378
  super(*args)
380
379
  end
381
380
 
@@ -568,7 +567,7 @@ module Mongoid
568
567
  # @return [ Object ] The result of the method call.
569
568
  #
570
569
  # @since 1.0.0
571
- ruby2_keywords def method_missing(name, *args, &block)
570
+ def method_missing(name, *args, &block)
572
571
  if klass.respond_to?(name)
573
572
  klass.send(:with_scope, self) do
574
573
  klass.send(name, *args, &block)
@@ -151,7 +151,7 @@ module Mongoid
151
151
  #
152
152
  # @since 2.4.0
153
153
  def to_key
154
- (persisted? || destroyed?) ? [ id.to_s ] : nil
154
+ (persisted? || destroyed?) ? [ _id.to_s ] : nil
155
155
  end
156
156
 
157
157
  # Return an array with this +Document+ only in it.
@@ -194,8 +194,8 @@ module Mongoid
194
194
  #
195
195
  # @param [ Hash ] options The options.
196
196
  #
197
- # @option options [ true, false ] :compact (Deprecated) Whether to include fields
198
- # with nil values in the json document.
197
+ # @option options [ true, false ] :compact Whether to include fields with
198
+ # nil values in the json document.
199
199
  #
200
200
  # @return [ Hash ] The document as json.
201
201
  #
@@ -203,7 +203,6 @@ module Mongoid
203
203
  def as_json(options = nil)
204
204
  rv = super
205
205
  if options && options[:compact]
206
- Mongoid.logger.warn('#as_json :compact option is deprecated. Please call #compact on the returned Hash object instead.')
207
206
  rv = rv.compact
208
207
  end
209
208
  rv
@@ -274,20 +273,6 @@ module Mongoid
274
273
  @model_cache_key ||= self.class.model_name.cache_key
275
274
  end
276
275
 
277
- # Implement this for calls to flatten on array.
278
- #
279
- # @example Get the document as an array.
280
- # document.to_ary
281
- #
282
- # @return [ nil ] Always nil.
283
- #
284
- # @since 2.1.0
285
- def to_ary
286
- nil
287
- end
288
-
289
- private
290
-
291
276
  def as_attributes
292
277
  return attributes if frozen?
293
278
  embedded_relations.each_pair do |name, meta|
@@ -4,24 +4,23 @@
4
4
  module Mongoid
5
5
  module Errors
6
6
 
7
- # This error is raised when calling #save! or .create! on a model when one
8
- # of the callbacks returns false.
7
+ # This error is raised when attempting to destroy a model which has
8
+ # an association with dependency option set to restrict.
9
9
  class DeleteRestriction < MongoidError
10
10
 
11
11
  # Create the new callbacks error.
12
12
  #
13
- # @example Create the new callbacks error.
14
- # Callbacks.new(Post, :create!)
15
- #
16
- # @param [ Class ] document
17
- # @param [ Symbol ] association
13
+ # @param [ Document ] document The document that was attempted to be
14
+ # destroyed.
15
+ # @param [ Symbol ] association_name The name of the dependent
16
+ # association that prevents the document from being deleted.
18
17
  #
19
18
  # @since 3.0.0
20
- def initialize(document, relation)
19
+ def initialize(document, association_name)
21
20
  super(
22
21
  compose_message(
23
22
  "delete_restriction",
24
- { document: document.class, relation: relation }
23
+ { document: document.class, relation: association_name }
25
24
  )
26
25
  )
27
26
  end
@@ -48,7 +48,7 @@ module Mongoid
48
48
  #
49
49
  # @return [ String ] A localized error message string.
50
50
  def translate(key, options)
51
- ::I18n.translate("#{BASE_KEY}.#{key}", **options)
51
+ ::I18n.translate("#{BASE_KEY}.#{key}", options)
52
52
  end
53
53
 
54
54
  # Create the problem.
@@ -8,10 +8,8 @@ require "mongoid/errors/criteria_argument_required"
8
8
  require "mongoid/errors/document_not_destroyed"
9
9
  require "mongoid/errors/document_not_found"
10
10
  require "mongoid/errors/eager_load"
11
- require "mongoid/errors/empty_config_file"
12
11
  require "mongoid/errors/in_memory_collation_not_supported"
13
12
  require "mongoid/errors/invalid_collection"
14
- require "mongoid/errors/invalid_config_file"
15
13
  require "mongoid/errors/invalid_config_option"
16
14
  require "mongoid/errors/invalid_dependent_strategy"
17
15
  require "mongoid/errors/invalid_field"
@@ -15,7 +15,7 @@ module Mongoid
15
15
  #
16
16
  # @since 3.0.0
17
17
  def __evolve_object_id__
18
- id
18
+ _id
19
19
  end
20
20
  end
21
21
  end
@@ -16,9 +16,8 @@ module Mongoid
16
16
  #
17
17
  # @since 3.0.0
18
18
  def mongoize(object)
19
- ::Boolean.evolve(object)
19
+ evolve(object)
20
20
  end
21
- alias :evolve :mongoize
22
21
  end
23
22
  end
24
23
  end
@@ -28,7 +28,7 @@ module Mongoid
28
28
  #
29
29
  # @since 1.0.0
30
30
  def is_a?(other)
31
- if other == ::Boolean || other.class == ::Boolean
31
+ if other == Mongoid::Boolean || other.class == Mongoid::Boolean
32
32
  return true
33
33
  end
34
34
  super(other)
@@ -117,7 +117,7 @@ module Mongoid
117
117
  #
118
118
  # @since 3.0.2
119
119
  def delete_id
120
- delete("_id") || delete("id") || delete(:id) || delete(:_id)
120
+ delete("_id") || delete(:_id) || delete("id") || delete(:id)
121
121
  end
122
122
 
123
123
  # Get the id attribute from this hash, whether it's prefixed with an
@@ -130,7 +130,7 @@ module Mongoid
130
130
  #
131
131
  # @since 2.3.2
132
132
  def extract_id
133
- self["_id"] || self["id"] || self[:id] || self[:_id]
133
+ self["_id"] || self[:_id] || self["id"] || self[:id]
134
134
  end
135
135
 
136
136
  # Fetch a nested value via dot syntax.
@@ -28,7 +28,7 @@ module Mongoid
28
28
  #
29
29
  # @since 1.0.0
30
30
  def is_a?(other)
31
- if other == ::Boolean || other.class == ::Boolean
31
+ if other == Mongoid::Boolean || other.class == Mongoid::Boolean
32
32
  return true
33
33
  end
34
34
  super(other)
@@ -13,6 +13,7 @@ module Mongoid
13
13
  extend ActiveSupport::Concern
14
14
 
15
15
  StringifiedSymbol = Mongoid::StringifiedSymbol
16
+ Boolean = Mongoid::Boolean
16
17
 
17
18
  # For fields defined with symbols use the correct class.
18
19
  #
@@ -37,10 +38,48 @@ module Mongoid
37
38
  time: Time
38
39
  }.with_indifferent_access
39
40
 
40
- # Constant for all names of the id field in a document.
41
+ # Constant for all names of the _id field in a document.
41
42
  #
42
- # @since 5.0.0
43
- IDS = [ :_id, :id, '_id', 'id' ].freeze
43
+ # This does not include aliases of _id field.
44
+ #
45
+ # @api private
46
+ IDS = [ :_id, '_id', ].freeze
47
+
48
+ module ClassMethods
49
+ # Returns the list of id fields for this model class, as both strings
50
+ # and symbols.
51
+ #
52
+ # @return [ Array<Symbol | String> ] List of id fields.
53
+ #
54
+ # @api private
55
+ def id_fields
56
+ IDS.dup.tap do |id_fields|
57
+ aliased_fields.each do |k, v|
58
+ if v == '_id'
59
+ id_fields << k.to_sym
60
+ id_fields << k
61
+ end
62
+ end
63
+ end
64
+ end
65
+
66
+ # Extracts the id field from the specified attributes hash based on
67
+ # aliases defined in this class.
68
+ #
69
+ # @param [ Hash ] attributes The attributes to inspect.
70
+ #
71
+ # @return [ Object ] The id value.
72
+ #
73
+ # @api private
74
+ def extract_id_field(attributes)
75
+ id_fields.each do |k|
76
+ if v = attributes[k]
77
+ return v
78
+ end
79
+ end
80
+ nil
81
+ end
82
+ end
44
83
 
45
84
  included do
46
85
  class_attribute :aliased_fields
@@ -62,8 +101,7 @@ module Mongoid
62
101
  type: BSON::ObjectId
63
102
  )
64
103
 
65
- alias :id :_id
66
- alias :id= :_id=
104
+ alias_attribute(:id, :_id)
67
105
  end
68
106
 
69
107
  # Apply all default values to the document which are not procs.
@@ -20,7 +20,7 @@ module Mongoid
20
20
  def inspect
21
21
  inspection = []
22
22
  inspection.concat(inspect_fields).concat(inspect_dynamic_fields)
23
- "#<#{self.class.name} _id: #{id}, #{inspection * ', '}>"
23
+ "#<#{self.class.name} _id: #{_id}, #{inspection * ', '}>"
24
24
  end
25
25
 
26
26
  private
@@ -125,7 +125,7 @@ module Mongoid
125
125
  # @return [ Document ] The document
126
126
  #
127
127
  # @since 2.3.0
128
- ruby2_keywords def run_callbacks(kind, *args, &block)
128
+ def run_callbacks(kind, *args, &block)
129
129
  cascadable_children(kind).each do |child|
130
130
  if child.run_callbacks(child_callback_type(kind, child), *args) == false
131
131
  return false
@@ -0,0 +1,41 @@
1
+ module Mongoid
2
+ module Matcher
3
+
4
+ # @api private
5
+ module Bits
6
+ def matches?(exists, value, condition)
7
+ case value
8
+ when BSON::Binary
9
+ value = value.data.split('').map { |n| '%02x' % n.ord }.join.to_i(16)
10
+ end
11
+ case condition
12
+ when Array
13
+ array_matches?(value, condition)
14
+ when BSON::Binary
15
+ int_cond = condition.data.split('').map { |n| '%02x' % n.ord }.join.to_i(16)
16
+ int_matches?(value, int_cond)
17
+ when Integer
18
+ if condition < 0
19
+ raise Errors::InvalidQuery, "Invalid value for $#{operator_name} argument: negative integers are not allowed: #{condition}"
20
+ end
21
+ int_matches?(value, condition)
22
+ when Float
23
+ if (int_cond = condition.to_i).to_f == condition
24
+ if int_cond < 0
25
+ raise Errors::InvalidQuery, "Invalid value for $#{operator_name} argument: negative numbers are not allowed: #{condition}"
26
+ end
27
+ int_matches?(value, int_cond)
28
+ else
29
+ raise Errors::InvalidQuery, "Invalid type for $#{operator_name} argument: not representable as an integer: #{condition}"
30
+ end
31
+ else
32
+ raise Errors::InvalidQuery, "Invalid type for $#{operator_name} argument: #{condition}"
33
+ end
34
+ end
35
+
36
+ module_function def operator_name
37
+ name.sub(/.*::/, '').sub(/\A(.)/) { |l| l.downcase }
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,20 @@
1
+ module Mongoid
2
+ module Matcher
3
+
4
+ # @api private
5
+ module BitsAllClear
6
+ include Bits
7
+ extend self
8
+
9
+ def array_matches?(value, condition)
10
+ condition.all? do |c|
11
+ value & (1<<c) == 0
12
+ end
13
+ end
14
+
15
+ def int_matches?(value, condition)
16
+ value & condition == 0
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mongoid
2
+ module Matcher
3
+
4
+ # @api private
5
+ module BitsAllSet
6
+ include Bits
7
+ extend self
8
+
9
+ def array_matches?(value, condition)
10
+ condition.all? do |c|
11
+ value & (1<<c) > 0
12
+ end
13
+ end
14
+
15
+ def int_matches?(value, condition)
16
+ value & condition == condition
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mongoid
2
+ module Matcher
3
+
4
+ # @api private
5
+ module BitsAnyClear
6
+ include Bits
7
+ extend self
8
+
9
+ def array_matches?(value, condition)
10
+ condition.any? do |c|
11
+ value & (1<<c) == 0
12
+ end
13
+ end
14
+
15
+ def int_matches?(value, condition)
16
+ value & condition < condition
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Mongoid
2
+ module Matcher
3
+
4
+ # @api private
5
+ module BitsAnySet
6
+ include Bits
7
+ extend self
8
+
9
+ def array_matches?(value, condition)
10
+ condition.any? do |c|
11
+ value & (1<<c) > 0
12
+ end
13
+ end
14
+
15
+ def int_matches?(value, condition)
16
+ value & condition > 0
17
+ end
18
+ end
19
+ end
20
+ end
@@ -12,6 +12,10 @@ module Mongoid
12
12
  end
13
13
  expr.all? do |k, expr_v|
14
14
  k = k.to_s
15
+ if k == "$comment"
16
+ # Nothing
17
+ return true
18
+ end
15
19
  if k.start_with?('$')
16
20
  ExpressionOperator.get(k).matches?(document, expr_v)
17
21
  else
@@ -5,6 +5,10 @@ module Mongoid
5
5
  module FieldOperator
6
6
  MAP = {
7
7
  '$all' => All,
8
+ '$bitsAllClear' => BitsAllClear,
9
+ '$bitsAllSet' => BitsAllSet,
10
+ '$bitsAnyClear' => BitsAnyClear,
11
+ '$bitsAnySet' => BitsAnySet,
8
12
  '$elemMatch' => ElemMatch,
9
13
  '$eq' => Eq,
10
14
  '$exists' => Exists,
@@ -13,11 +17,13 @@ module Mongoid
13
17
  '$in' => In,
14
18
  '$lt' => Lt,
15
19
  '$lte' => Lte,
20
+ '$mod' => Mod,
16
21
  '$nin' => Nin,
17
22
  '$ne' => Ne,
18
23
  '$not' => Not,
19
24
  '$regex' => Regex,
20
25
  '$size' => Size,
26
+ '$type' => Type,
21
27
  }.freeze
22
28
 
23
29
  module_function def get(op)
@@ -0,0 +1,17 @@
1
+ module Mongoid
2
+ module Matcher
3
+
4
+ # @api private
5
+ module Mod
6
+ module_function def matches?(exists, value, condition)
7
+ unless Array === condition
8
+ raise Errors::InvalidQuery, "Unknown $mod argument #{condition}"
9
+ end
10
+ if condition.length != 2
11
+ raise Errors::InvalidQuery, "Malformed $mod argument #{condition}, should have 2 elements"
12
+ end
13
+ condition[1] == value%condition[0]
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,99 @@
1
+ module Mongoid
2
+ module Matcher
3
+
4
+ # @see https://docs.mongodb.com/manual/reference/operator/query/type/
5
+ #
6
+ # @api private
7
+ module Type
8
+ module_function def matches?(exists, value, condition)
9
+ conditions = case condition
10
+ when Array
11
+ condition
12
+ when Integer
13
+ [condition]
14
+ else
15
+ raise Errors::InvalidQuery, "Unknown $type argument: #{condition}"
16
+ end
17
+ conditions.each do |condition|
18
+ if one_matches?(exists, value, condition)
19
+ return true
20
+ end
21
+ end
22
+ false
23
+ end
24
+
25
+ module_function def one_matches?(exists, value, condition)
26
+ case condition
27
+ when 1
28
+ # Double
29
+ Float === value
30
+ when 2
31
+ # String
32
+ String === value
33
+ when 3
34
+ # Object
35
+ Hash === value
36
+ when 4
37
+ # Array
38
+ Array === value
39
+ when 5
40
+ # Binary data
41
+ BSON::Binary === value
42
+ when 6
43
+ # Undefined
44
+ BSON::Undefined === value
45
+ when 7
46
+ # ObjectId
47
+ BSON::ObjectId === value
48
+ when 8
49
+ # Boolean
50
+ TrueClass === value || FalseClass === value
51
+ when 9
52
+ # Date
53
+ Date === value || Time === value || DateTime === value
54
+ when 10
55
+ # Null
56
+ exists && NilClass === value
57
+ when 11
58
+ # Regex
59
+ Regexp::Raw === value || ::Regexp === value
60
+ when 12
61
+ # DBPointer deprecated
62
+ BSON::DbPointer === value
63
+ when 13
64
+ # JavaScript
65
+ BSON::Code === value
66
+ when 14
67
+ # Symbol deprecated
68
+ Symbol === value || BSON::Symbol::Raw === value
69
+ when 15
70
+ # Javascript with code deprecated
71
+ BSON::CodeWithScope === value
72
+ when 16
73
+ # 32-bit int
74
+ BSON::Int32 === value || Integer === value && (-2**32..2**32-1).include?(value)
75
+ when 17
76
+ # Timestamp
77
+ BSON::Timestamp === value
78
+ when 18
79
+ # Long
80
+ BSON::Int64 === value ||
81
+ Integer === value &&
82
+ (-2**64..2**64-1).include?(value) &&
83
+ !(-2**32..2**32-1).include?(value)
84
+ when 19
85
+ # Decimal
86
+ BSON::Decimal128 === value
87
+ when -1
88
+ # minKey
89
+ BSON::MinKey === value
90
+ when 127
91
+ # maxKey
92
+ BSON::MaxKey === value
93
+ else
94
+ raise Errors::InvalidQuery, "Unknown $type argument: #{condition}"
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end