mongoid 7.2.6 → 7.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (154) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/Rakefile +16 -0
  4. data/lib/config/locales/en.yml +2 -2
  5. data/lib/mongoid/association/accessors.rb +13 -1
  6. data/lib/mongoid/association/constrainable.rb +1 -1
  7. data/lib/mongoid/association/depending.rb +4 -4
  8. data/lib/mongoid/association/embedded/batchable.rb +1 -1
  9. data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
  10. data/lib/mongoid/association/embedded/embeds_many/proxy.rb +10 -3
  11. data/lib/mongoid/association/nested/many.rb +1 -1
  12. data/lib/mongoid/association/nested/one.rb +4 -2
  13. data/lib/mongoid/association/proxy.rb +6 -1
  14. data/lib/mongoid/association/referenced/auto_save.rb +2 -2
  15. data/lib/mongoid/association/referenced/has_many/enumerable.rb +490 -496
  16. data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
  17. data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
  18. data/lib/mongoid/atomic.rb +26 -2
  19. data/lib/mongoid/attributes/projector.rb +120 -0
  20. data/lib/mongoid/attributes.rb +24 -13
  21. data/lib/mongoid/cacheable.rb +2 -2
  22. data/lib/mongoid/clients/factory.rb +22 -8
  23. data/lib/mongoid/clients.rb +1 -1
  24. data/lib/mongoid/config.rb +19 -2
  25. data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
  26. data/lib/mongoid/copyable.rb +1 -1
  27. data/lib/mongoid/criteria/findable.rb +1 -1
  28. data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
  29. data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
  30. data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
  31. data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
  32. data/lib/mongoid/criteria/queryable/selectable.rb +8 -8
  33. data/lib/mongoid/criteria.rb +4 -5
  34. data/lib/mongoid/document.rb +1 -15
  35. data/lib/mongoid/errors/delete_restriction.rb +8 -9
  36. data/lib/mongoid/evolvable.rb +1 -1
  37. data/lib/mongoid/extensions/boolean.rb +1 -2
  38. data/lib/mongoid/extensions/false_class.rb +1 -1
  39. data/lib/mongoid/extensions/hash.rb +2 -2
  40. data/lib/mongoid/extensions/true_class.rb +1 -1
  41. data/lib/mongoid/fields.rb +43 -5
  42. data/lib/mongoid/inspectable.rb +1 -1
  43. data/lib/mongoid/matcher/bits.rb +41 -0
  44. data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
  45. data/lib/mongoid/matcher/bits_all_set.rb +20 -0
  46. data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
  47. data/lib/mongoid/matcher/bits_any_set.rb +20 -0
  48. data/lib/mongoid/matcher/expression.rb +4 -0
  49. data/lib/mongoid/matcher/field_operator.rb +6 -0
  50. data/lib/mongoid/matcher/mod.rb +17 -0
  51. data/lib/mongoid/matcher/type.rb +99 -0
  52. data/lib/mongoid/matcher.rb +7 -0
  53. data/lib/mongoid/persistable/deletable.rb +1 -2
  54. data/lib/mongoid/persistable/destroyable.rb +8 -2
  55. data/lib/mongoid/persistable/updatable.rb +27 -2
  56. data/lib/mongoid/query_cache.rb +35 -29
  57. data/lib/mongoid/selectable.rb +5 -7
  58. data/lib/mongoid/shardable.rb +21 -5
  59. data/lib/mongoid/touchable.rb +33 -4
  60. data/lib/mongoid/version.rb +1 -1
  61. data/spec/integration/associations/embeds_many_spec.rb +44 -0
  62. data/spec/integration/associations/has_one_spec.rb +48 -0
  63. data/spec/integration/criteria/date_field_spec.rb +1 -1
  64. data/spec/integration/document_spec.rb +9 -0
  65. data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
  66. data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
  67. data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
  68. data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
  69. data/spec/integration/matcher_operator_data/comment.yml +22 -0
  70. data/spec/integration/matcher_operator_data/in.yml +16 -0
  71. data/spec/integration/matcher_operator_data/mod.yml +55 -0
  72. data/spec/integration/matcher_operator_data/type.yml +70 -0
  73. data/spec/integration/matcher_operator_data/type_array.yml +16 -0
  74. data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
  75. data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
  76. data/spec/integration/matcher_operator_data/type_code.yml +26 -0
  77. data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
  78. data/spec/integration/matcher_operator_data/type_date.yml +39 -0
  79. data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
  80. data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
  81. data/spec/integration/matcher_operator_data/type_double.yml +15 -0
  82. data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
  83. data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
  84. data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
  85. data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
  86. data/spec/integration/matcher_operator_data/type_null.yml +23 -0
  87. data/spec/integration/matcher_operator_data/type_object.yml +23 -0
  88. data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
  89. data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
  90. data/spec/integration/matcher_operator_data/type_string.yml +15 -0
  91. data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
  92. data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
  93. data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
  94. data/spec/lite_spec_helper.rb +2 -0
  95. data/spec/mongoid/association/depending_spec.rb +391 -352
  96. data/spec/mongoid/association/nested/one_spec.rb +18 -14
  97. data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -8
  98. data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
  99. data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
  100. data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +245 -93
  101. data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +6 -6
  102. data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
  103. data/spec/mongoid/atomic/paths_spec.rb +64 -12
  104. data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
  105. data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
  106. data/spec/mongoid/attributes/projector_spec.rb +41 -0
  107. data/spec/mongoid/attributes_spec.rb +98 -6
  108. data/spec/mongoid/clients/factory_spec.rb +48 -0
  109. data/spec/mongoid/config_spec.rb +106 -1
  110. data/spec/mongoid/contextual/mongo_spec.rb +2 -2
  111. data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
  112. data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
  113. data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
  114. data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
  115. data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
  116. data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
  117. data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
  118. data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
  119. data/spec/mongoid/criteria_projection_spec.rb +411 -0
  120. data/spec/mongoid/criteria_spec.rb +0 -275
  121. data/spec/mongoid/document_spec.rb +13 -13
  122. data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
  123. data/spec/mongoid/extensions/false_class_spec.rb +1 -1
  124. data/spec/mongoid/extensions/string_spec.rb +5 -5
  125. data/spec/mongoid/extensions/true_class_spec.rb +1 -1
  126. data/spec/mongoid/fields/localized_spec.rb +4 -4
  127. data/spec/mongoid/fields_spec.rb +4 -4
  128. data/spec/mongoid/inspectable_spec.rb +12 -4
  129. data/spec/mongoid/persistable/deletable_spec.rb +175 -1
  130. data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
  131. data/spec/mongoid/persistable/savable_spec.rb +3 -5
  132. data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
  133. data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
  134. data/spec/mongoid/reloadable_spec.rb +18 -1
  135. data/spec/mongoid/shardable_spec.rb +44 -0
  136. data/spec/mongoid/touchable_spec.rb +122 -16
  137. data/spec/mongoid/touchable_spec_models.rb +54 -0
  138. data/spec/mongoid/validatable_spec.rb +1 -1
  139. data/spec/spec_helper.rb +6 -2
  140. data/spec/support/client_registry.rb +9 -0
  141. data/spec/support/models/bolt.rb +8 -0
  142. data/spec/support/models/hole.rb +13 -0
  143. data/spec/support/models/mop.rb +0 -1
  144. data/spec/support/models/nut.rb +8 -0
  145. data/spec/support/models/person.rb +6 -0
  146. data/spec/support/models/sealer.rb +8 -0
  147. data/spec/support/models/shirt.rb +12 -0
  148. data/spec/support/models/spacer.rb +8 -0
  149. data/spec/support/models/threadlocker.rb +8 -0
  150. data/spec/support/models/washer.rb +8 -0
  151. data.tar.gz.sig +0 -0
  152. metadata +97 -3
  153. metadata.gz.sig +0 -0
  154. data/spec/support/cluster_config.rb +0 -158
@@ -33,4 +33,4 @@ module Mongoid
33
33
  end
34
34
  end
35
35
 
36
- ::Boolean.__send__(:extend, Mongoid::Criteria::Queryable::Extensions::Boolean::ClassMethods)
36
+ Mongoid::Boolean.__send__(:extend, Mongoid::Criteria::Queryable::Extensions::Boolean::ClassMethods)
@@ -1,10 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
  # encoding: utf-8
3
3
 
4
- unless defined?(Boolean)
5
- class Boolean; end
6
- end
7
-
8
4
  if defined?(ActiveSupport)
9
5
  unless defined?(ActiveSupport::TimeWithZone)
10
6
  require "active_support/time_with_zone"
@@ -227,7 +227,16 @@ module Mongoid
227
227
  end
228
228
 
229
229
  # Takes a criteria hash and expands Key objects into hashes containing
230
- # MQL corresponding to said key objects.
230
+ # MQL corresponding to said key objects. Also converts the input to
231
+ # BSON::Document to permit indifferent access.
232
+ #
233
+ # The argument must be a hash containing key-value pairs of the
234
+ # following forms:
235
+ # - {field_name: value}
236
+ # - {'field_name' => value}
237
+ # - {key_instance: value}
238
+ # - {:$operator => operator_value_expression}
239
+ # - {'$operator' => operator_value_expression}
231
240
  #
232
241
  # Ruby does not permit multiple symbol operators. For example,
233
242
  # {:foo.gt => 1, :foo.gt => 2} is collapsed to {:foo.gt => 2} by the
@@ -237,19 +246,23 @@ module Mongoid
237
246
  # Similarly, this method should never need to expand a literal value
238
247
  # and an operator at the same time.
239
248
  #
249
+ # This method effectively converts symbol keys to string keys in
250
+ # the input +expr+, such that the downstream code can assume that
251
+ # conditions always contain string keys.
252
+ #
240
253
  # @param [ Hash ] expr Criteria including Key instances.
241
254
  #
242
- # @return [ Hash ] The expanded criteria.
255
+ # @return [ BSON::Document ] The expanded criteria.
243
256
  private def _mongoid_expand_keys(expr)
244
257
  unless expr.is_a?(Hash)
245
258
  raise ArgumentError, 'Argument must be a Hash'
246
259
  end
247
260
 
248
- result = {}
261
+ result = BSON::Document.new
249
262
  expr.each do |field, value|
250
- field.__expr_part__(value.__expand_complex__).each do |k, v|
251
- if result[k]
252
- if result[k].is_a?(Hash)
263
+ field.__expr_part__(value.__expand_complex__, negating?).each do |k, v|
264
+ if existing = result[k]
265
+ if existing.is_a?(Hash)
253
266
  # Existing value is an operator.
254
267
  # If new value is also an operator, ensure there are no
255
268
  # conflicts and add
@@ -257,8 +270,8 @@ module Mongoid
257
270
  # The new value is also an operator.
258
271
  # If there are no conflicts, combine the hashes, otherwise
259
272
  # add new conditions to top level with $and.
260
- if (v.keys & result[k].keys).empty?
261
- result[k].update(v)
273
+ if (v.keys & existing.keys).empty?
274
+ existing.update(v)
262
275
  else
263
276
  raise NotImplementedError, 'Ruby does not allow same symbol operator with different values'
264
277
  result['$and'] ||= []
@@ -266,26 +279,39 @@ module Mongoid
266
279
  end
267
280
  else
268
281
  # The new value is a simple value.
269
- # If there isn't an $eq operator already in the query,
270
- # transform the new value into an $eq operator and add it
271
- # to the existing hash. Otherwise add the new condition
272
- # with $and to the top level.
273
- if result[k].key?('$eq')
282
+ # Transform the implicit equality to either $eq or $regexp
283
+ # depending on the type of the argument. See
284
+ # https://docs.mongodb.com/manual/reference/operator/query/eq/#std-label-eq-usage-examples
285
+ # for the description of relevant server behavior.
286
+ op = case v
287
+ when Regexp, BSON::Regexp::Raw
288
+ '$regex'
289
+ else
290
+ '$eq'
291
+ end
292
+ # If there isn't an $eq/$regex operator already in the
293
+ # query, transform the new value into an operator
294
+ # expression and add it to the existing hash. Otherwise
295
+ # add the new condition with $and to the top level.
296
+ if existing.key?(op)
274
297
  raise NotImplementedError, 'Ruby does not allow same symbol operator with different values'
275
298
  result['$and'] ||= []
276
299
  result['$and'] << {k => v}
277
300
  else
278
- result[k].update('$eq' => v)
301
+ existing.update(op => v)
279
302
  end
280
303
  end
281
304
  else
282
305
  # Existing value is a simple value.
283
- # If we are adding an operator, and the operator is not $eq,
284
- # convert existing value into $eq and add the new operator
285
- # to the same hash. Otherwise add the new condition with $and
286
- # to the top level.
287
- if v.is_a?(Hash) && !v.key?('$eq')
288
- result[k] = {'$eq' => result[k]}.update(v)
306
+ # See the notes above about transformations to $eq/$regex.
307
+ op = case existing
308
+ when Regexp, BSON::Regexp::Raw
309
+ '$regex'
310
+ else
311
+ '$eq'
312
+ end
313
+ if v.is_a?(Hash) && !v.key?(op)
314
+ result[k] = {op => existing}.update(v)
289
315
  else
290
316
  raise NotImplementedError, 'Ruby does not allow same symbol operator with different values'
291
317
  result['$and'] ||= []
@@ -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
@@ -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
893
  if field_s.start_with?('$')
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!
@@ -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
 
@@ -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.
@@ -274,20 +274,6 @@ module Mongoid
274
274
  @model_cache_key ||= self.class.model_name.cache_key
275
275
  end
276
276
 
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
277
  def as_attributes
292
278
  return attributes if frozen?
293
279
  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
@@ -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
@@ -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