mongoid 7.2.6 → 7.3.0

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