mongoid 7.1.1 → 7.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/mongoid/association/embedded/embeds_many.rb +2 -1
- data/lib/mongoid/association/embedded/embeds_one.rb +2 -1
- data/lib/mongoid/association/proxy.rb +1 -1
- data/lib/mongoid/atomic.rb +13 -3
- data/lib/mongoid/criteria.rb +7 -1
- data/lib/mongoid/criteria/modifiable.rb +2 -1
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +1 -1
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +3 -3
- data/lib/mongoid/criteria/queryable/mergeable.rb +75 -8
- data/lib/mongoid/criteria/queryable/selectable.rb +28 -8
- data/lib/mongoid/extensions/hash.rb +4 -2
- data/lib/mongoid/extensions/regexp.rb +1 -1
- data/lib/mongoid/fields.rb +2 -1
- data/lib/mongoid/matchable/regexp.rb +2 -2
- data/lib/mongoid/persistable/pushable.rb +4 -1
- data/lib/mongoid/persistence_context.rb +6 -6
- data/lib/mongoid/query_cache.rb +2 -1
- data/lib/mongoid/validatable/uniqueness.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/model/templates/model.rb.tt +1 -1
- data/spec/integration/app_spec.rb +192 -0
- data/spec/integration/associations/embedded_spec.rb +54 -0
- data/spec/integration/criteria/logical_spec.rb +13 -0
- data/spec/lite_spec_helper.rb +11 -4
- data/spec/mongoid/association/embedded/embeds_many_models.rb +19 -0
- data/spec/mongoid/association/embedded/embeds_many_spec.rb +10 -0
- data/spec/mongoid/association/embedded/embeds_one_spec.rb +0 -2
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/proxy_spec.rb +2 -1
- data/spec/mongoid/association/referenced/has_many/proxy_spec.rb +2 -1
- data/spec/mongoid/clients/options_spec.rb +2 -2
- data/spec/mongoid/clients/sessions_spec.rb +8 -4
- data/spec/mongoid/clients/transactions_spec.rb +20 -8
- data/spec/mongoid/clients_spec.rb +2 -2
- data/spec/mongoid/contextual/atomic_spec.rb +22 -11
- data/spec/mongoid/contextual/map_reduce_spec.rb +20 -5
- data/spec/mongoid/contextual/mongo_spec.rb +76 -53
- data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +7 -7
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +45 -12
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +480 -198
- data/spec/mongoid/criteria_spec.rb +4 -2
- data/spec/mongoid/document_persistence_context_spec.rb +33 -0
- data/spec/mongoid/indexable_spec.rb +6 -4
- data/spec/mongoid/matchable/default_spec.rb +1 -1
- data/spec/mongoid/matchable/regexp_spec.rb +2 -2
- data/spec/mongoid/matchable_spec.rb +2 -2
- data/spec/mongoid/query_cache_spec.rb +2 -1
- data/spec/mongoid/relations/proxy_spec.rb +1 -1
- data/spec/mongoid/scopable_spec.rb +2 -1
- data/spec/mongoid/shardable_models.rb +1 -1
- data/spec/mongoid/shardable_spec.rb +2 -2
- data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
- data/spec/mongoid/tasks/database_spec.rb +1 -1
- data/spec/spec_helper.rb +0 -31
- data/spec/support/child_process_helper.rb +76 -0
- data/spec/support/cluster_config.rb +3 -3
- data/spec/support/constraints.rb +26 -10
- data/spec/support/spec_config.rb +12 -4
- metadata +8 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd29f8f1d696ba937654fcd72eb3669ac9ba501465828b7eba0f7b707e606f5b
|
4
|
+
data.tar.gz: c9f4a8dbb8a105a7e596019760d100913ddd008972b34f7595674ad7c49d4159
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0e00e8d47e7af2fec23380035bcdbd0badc438552aed52aa0f462e246274e7f77220190d99bb6a83a1a90b8e0a41d19103c94fa454382635a2c193d52260c322
|
7
|
+
data.tar.gz: 709300f2570059e460cd341cbaffe7da6328df142825bb726b65cbc377d6ba5129cf7fc973a40fc2de10a50307f49ac0f71db98b0edbb8a65c9cb33910e9d66f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
@@ -200,7 +200,8 @@ module Mongoid
|
|
200
200
|
def determine_inverses(other)
|
201
201
|
matches = relation_class.relations.values.select do |rel|
|
202
202
|
relation_complements.include?(rel.class) &&
|
203
|
-
|
203
|
+
# https://jira.mongodb.org/browse/MONGOID-4882
|
204
|
+
rel.relation_class_name.sub(/\A::/, '') == inverse_class_name
|
204
205
|
end
|
205
206
|
if matches.size > 1
|
206
207
|
raise Errors::AmbiguousRelationship.new(relation_class, @owner_class, name, matches)
|
@@ -162,7 +162,8 @@ module Mongoid
|
|
162
162
|
def determine_inverses(other)
|
163
163
|
matches = relation_class.relations.values.select do |rel|
|
164
164
|
relation_complements.include?(rel.class) &&
|
165
|
-
|
165
|
+
# https://jira.mongodb.org/browse/MONGOID-4882
|
166
|
+
rel.relation_class_name.sub(/\A::/, '') == inverse_class_name
|
166
167
|
|
167
168
|
end
|
168
169
|
if matches.size > 1
|
@@ -16,7 +16,7 @@ module Mongoid
|
|
16
16
|
# We undefine most methods to get them sent through to the target.
|
17
17
|
instance_methods.each do |method|
|
18
18
|
undef_method(method) unless
|
19
|
-
method =~
|
19
|
+
method =~ /\A(__.*|send|object_id|equal\?|respond_to\?|tap|public_send|extend_proxy|extend_proxies)\z/
|
20
20
|
end
|
21
21
|
|
22
22
|
include Threaded::Lifecycle
|
data/lib/mongoid/atomic.rb
CHANGED
@@ -38,7 +38,9 @@ module Mongoid
|
|
38
38
|
# @since 2.2.0
|
39
39
|
def add_atomic_pull(document)
|
40
40
|
document.flagged_for_destroy = true
|
41
|
-
|
41
|
+
key = document.association_name.to_s
|
42
|
+
delayed_atomic_pulls[key] ||= []
|
43
|
+
delayed_atomic_pulls[key] << document
|
42
44
|
end
|
43
45
|
|
44
46
|
# Add an atomic unset for the document.
|
@@ -53,7 +55,9 @@ module Mongoid
|
|
53
55
|
# @since 3.0.0
|
54
56
|
def add_atomic_unset(document)
|
55
57
|
document.flagged_for_destroy = true
|
56
|
-
|
58
|
+
key = document.association_name.to_s
|
59
|
+
delayed_atomic_unsets[key] ||= []
|
60
|
+
delayed_atomic_unsets[key] << document
|
57
61
|
end
|
58
62
|
|
59
63
|
# Returns path of the attribute for modification
|
@@ -191,7 +195,13 @@ module Mongoid
|
|
191
195
|
#
|
192
196
|
# @since 2.1.0
|
193
197
|
def atomic_paths
|
194
|
-
@atomic_paths ||=
|
198
|
+
@atomic_paths ||= begin
|
199
|
+
if _association
|
200
|
+
_association.path(self)
|
201
|
+
else
|
202
|
+
Atomic::Paths::Root.new(self)
|
203
|
+
end
|
204
|
+
end
|
195
205
|
end
|
196
206
|
|
197
207
|
# Get all the attributes that need to be pulled.
|
data/lib/mongoid/criteria.rb
CHANGED
@@ -450,7 +450,13 @@ module Mongoid
|
|
450
450
|
#
|
451
451
|
# @since 3.1.0
|
452
452
|
def for_js(javascript, scope = {})
|
453
|
-
|
453
|
+
code = if scope.empty?
|
454
|
+
# CodeWithScope is not supported for $where as of MongoDB 4.4
|
455
|
+
BSON::Code.new(javascript)
|
456
|
+
else
|
457
|
+
BSON::CodeWithScope.new(javascript, scope)
|
458
|
+
end
|
459
|
+
js_query(code)
|
454
460
|
end
|
455
461
|
|
456
462
|
private
|
@@ -60,7 +60,7 @@ module Mongoid
|
|
60
60
|
#
|
61
61
|
# @since 1.0.0
|
62
62
|
def __numeric__(object)
|
63
|
-
object.to_s =~ /(
|
63
|
+
object.to_s =~ /(\A[-+]?[0-9]+\z)|(\.0+\z)|(\.\z)/ ? object.to_i : Float(object)
|
64
64
|
end
|
65
65
|
|
66
66
|
# Evolve the object to an integer.
|
@@ -12,7 +12,7 @@ module Mongoid
|
|
12
12
|
# Is the object a regexp?
|
13
13
|
#
|
14
14
|
# @example Is the object a regex?
|
15
|
-
#
|
15
|
+
# /\A[123]/.regexp?
|
16
16
|
#
|
17
17
|
# @return [ true ] Always true.
|
18
18
|
#
|
@@ -24,7 +24,7 @@ module Mongoid
|
|
24
24
|
# Evolve the object into a regex.
|
25
25
|
#
|
26
26
|
# @example Evolve the object to a regex.
|
27
|
-
# Regexp.evolve("
|
27
|
+
# Regexp.evolve("\A[123]")
|
28
28
|
#
|
29
29
|
# @param [ Regexp, String ] object The object to evolve.
|
30
30
|
#
|
@@ -55,7 +55,7 @@ module Mongoid
|
|
55
55
|
# Evolve the object into a raw bson regex.
|
56
56
|
#
|
57
57
|
# @example Evolve the object to a regex.
|
58
|
-
# BSON::Regexp::Raw.evolve("
|
58
|
+
# BSON::Regexp::Raw.evolve("\\A[123]")
|
59
59
|
#
|
60
60
|
# @param [ BSON::Regexp::Raw, String ] object The object to evolve.
|
61
61
|
#
|
@@ -163,7 +163,7 @@ module Mongoid
|
|
163
163
|
if expr.is_a?(Selectable)
|
164
164
|
expr = expr.selector
|
165
165
|
end
|
166
|
-
normalized =
|
166
|
+
normalized = _mongoid_expand_keys(expr)
|
167
167
|
sel.store(operator, result_criteria.push(normalized))
|
168
168
|
end
|
169
169
|
end
|
@@ -190,9 +190,9 @@ module Mongoid
|
|
190
190
|
sel = query.selector
|
191
191
|
_mongoid_flatten_arrays(criteria).each do |criterion|
|
192
192
|
if criterion.is_a?(Selectable)
|
193
|
-
expr =
|
193
|
+
expr = _mongoid_expand_keys(criterion.selector)
|
194
194
|
else
|
195
|
-
expr = criterion
|
195
|
+
expr = _mongoid_expand_keys(criterion)
|
196
196
|
end
|
197
197
|
if sel.empty?
|
198
198
|
sel.store(operator, [expr])
|
@@ -212,7 +212,7 @@ module Mongoid
|
|
212
212
|
# explicitly only expands Array objects and Array subclasses.
|
213
213
|
private def _mongoid_flatten_arrays(array)
|
214
214
|
out = []
|
215
|
-
pending = array
|
215
|
+
pending = array.dup
|
216
216
|
until pending.empty?
|
217
217
|
item = pending.shift
|
218
218
|
if item.nil?
|
@@ -226,11 +226,78 @@ module Mongoid
|
|
226
226
|
out
|
227
227
|
end
|
228
228
|
|
229
|
-
#
|
230
|
-
|
231
|
-
|
232
|
-
|
229
|
+
# Takes a criteria hash and expands Key objects into hashes containing
|
230
|
+
# MQL corresponding to said key objects.
|
231
|
+
#
|
232
|
+
# Ruby does not permit multiple symbol operators. For example,
|
233
|
+
# {:foo.gt => 1, :foo.gt => 2} is collapsed to {:foo.gt => 2} by the
|
234
|
+
# language. Therefore this method never has to deal with multiple
|
235
|
+
# identical operators.
|
236
|
+
#
|
237
|
+
# Similarly, this method should never need to expand a literal value
|
238
|
+
# and an operator at the same time.
|
239
|
+
#
|
240
|
+
# @param [ Hash ] Criteria including Key instances.
|
241
|
+
#
|
242
|
+
# @return [ Hash ] Expanded criteria.
|
243
|
+
private def _mongoid_expand_keys(expr)
|
244
|
+
unless expr.is_a?(Hash)
|
245
|
+
raise ArgumentError, 'Argument must be a Hash'
|
246
|
+
end
|
247
|
+
|
248
|
+
result = {}
|
249
|
+
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)
|
253
|
+
# Existing value is an operator.
|
254
|
+
# If new value is also an operator, ensure there are no
|
255
|
+
# conflicts and add
|
256
|
+
if v.is_a?(Hash)
|
257
|
+
# The new value is also an operator.
|
258
|
+
# If there are no conflicts, combine the hashes, otherwise
|
259
|
+
# add new conditions to top level with $and.
|
260
|
+
if (v.keys & result[k].keys).empty?
|
261
|
+
result[k].update(v)
|
262
|
+
else
|
263
|
+
raise NotImplementedError, 'Ruby does not allow same symbol operator with different values'
|
264
|
+
result['$and'] ||= []
|
265
|
+
result['$and'] << {k => v}
|
266
|
+
end
|
267
|
+
else
|
268
|
+
# 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')
|
274
|
+
raise NotImplementedError, 'Ruby does not allow same symbol operator with different values'
|
275
|
+
result['$and'] ||= []
|
276
|
+
result['$and'] << {k => v}
|
277
|
+
else
|
278
|
+
result[k].update('$eq' => v)
|
279
|
+
end
|
280
|
+
end
|
281
|
+
else
|
282
|
+
# 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)
|
289
|
+
else
|
290
|
+
raise NotImplementedError, 'Ruby does not allow same symbol operator with different values'
|
291
|
+
result['$and'] ||= []
|
292
|
+
result['$and'] << {k => v}
|
293
|
+
end
|
294
|
+
end
|
295
|
+
else
|
296
|
+
result[k] = v
|
297
|
+
end
|
298
|
+
end
|
233
299
|
end
|
300
|
+
result
|
234
301
|
end
|
235
302
|
|
236
303
|
# Adds the criterion to the existing selection.
|
@@ -89,11 +89,27 @@ module Mongoid
|
|
89
89
|
if new_s.is_a?(Selectable)
|
90
90
|
new_s = new_s.selector
|
91
91
|
end
|
92
|
-
normalized =
|
92
|
+
normalized = _mongoid_expand_keys(new_s)
|
93
93
|
normalized.each do |k, v|
|
94
94
|
k = k.to_s
|
95
95
|
if c.selector[k]
|
96
|
-
|
96
|
+
# There is already a condition on k.
|
97
|
+
# If v is an operator, and all existing conditions are
|
98
|
+
# also operators, and v isn't present in existing conditions,
|
99
|
+
# we can add to existing conditions.
|
100
|
+
# Otherwise use $and.
|
101
|
+
if v.is_a?(Hash) &&
|
102
|
+
v.length == 1 &&
|
103
|
+
(new_k = v.keys.first).start_with?('$') &&
|
104
|
+
(existing_kv = c.selector[k]).is_a?(Hash) &&
|
105
|
+
!existing_kv.key?(new_k) &&
|
106
|
+
existing_kv.keys.all? { |sub_k| sub_k.start_with?('$') }
|
107
|
+
then
|
108
|
+
merged_v = c.selector[k].merge(v)
|
109
|
+
c.selector.store(k, merged_v)
|
110
|
+
else
|
111
|
+
c = c.send(:__multi__, [k => v], '$and')
|
112
|
+
end
|
97
113
|
else
|
98
114
|
c.selector.store(k, v)
|
99
115
|
end
|
@@ -567,17 +583,21 @@ module Mongoid
|
|
567
583
|
if new_s.is_a?(Selectable)
|
568
584
|
new_s = new_s.selector
|
569
585
|
end
|
570
|
-
new_s.each do |k, v|
|
586
|
+
_mongoid_expand_keys(new_s).each do |k, v|
|
571
587
|
k = k.to_s
|
572
588
|
if c.selector[k] || k[0] == ?$
|
573
589
|
c = c.send(:__multi__, [{'$nor' => [{k => v}]}], '$and')
|
574
590
|
else
|
575
|
-
if v.is_a?(
|
576
|
-
|
591
|
+
if v.is_a?(Hash)
|
592
|
+
c = c.send(:__multi__, [{'$nor' => [{k => v}]}], '$and')
|
577
593
|
else
|
578
|
-
|
594
|
+
if v.is_a?(Regexp)
|
595
|
+
negated_operator = '$not'
|
596
|
+
else
|
597
|
+
negated_operator = '$ne'
|
598
|
+
end
|
599
|
+
c = c.send(:__override__, {k => v}, negated_operator)
|
579
600
|
end
|
580
|
-
c = c.send(:__override__, {k => v}, negated_operator)
|
581
601
|
end
|
582
602
|
end
|
583
603
|
c
|
@@ -665,7 +685,7 @@ module Mongoid
|
|
665
685
|
# and add the result to self.
|
666
686
|
exprs = criteria.map do |criterion|
|
667
687
|
if criterion.is_a?(Selectable)
|
668
|
-
|
688
|
+
_mongoid_expand_keys(criterion.selector)
|
669
689
|
else
|
670
690
|
Hash[criterion.map do |k, v|
|
671
691
|
if k.is_a?(Symbol)
|
@@ -48,9 +48,11 @@ module Mongoid
|
|
48
48
|
value.each_pair do |_key, _value|
|
49
49
|
value[_key] = (key == "$rename") ? _value.to_s : mongoize_for(key, klass, _key, _value)
|
50
50
|
end
|
51
|
-
|
51
|
+
consolidated[key] ||= {}
|
52
|
+
consolidated[key].update(value)
|
52
53
|
else
|
53
|
-
|
54
|
+
consolidated["$set"] ||= {}
|
55
|
+
consolidated["$set"].update(key => mongoize_for(key, klass, key, value))
|
54
56
|
end
|
55
57
|
end
|
56
58
|
consolidated
|
data/lib/mongoid/fields.rb
CHANGED
@@ -500,7 +500,8 @@ module Mongoid
|
|
500
500
|
def create_translations_getter(name, meth)
|
501
501
|
generated_methods.module_eval do
|
502
502
|
re_define_method("#{meth}_translations") do
|
503
|
-
|
503
|
+
attributes[name] ||= {}
|
504
|
+
attributes[name].with_indifferent_access
|
504
505
|
end
|
505
506
|
alias_method :"#{meth}_t", :"#{meth}_translations"
|
506
507
|
end
|
@@ -10,8 +10,8 @@ module Mongoid
|
|
10
10
|
# Does the supplied query match the attribute?
|
11
11
|
#
|
12
12
|
# @example Does this match?
|
13
|
-
# matcher._matches?(
|
14
|
-
# matcher._matches?(BSON::Regex::Raw.new("
|
13
|
+
# matcher._matches?(/\AEm/)
|
14
|
+
# matcher._matches?(BSON::Regex::Raw.new("\\AEm"))
|
15
15
|
#
|
16
16
|
# @param [ BSON::Regexp::Raw, Regexp ] regexp The regular expression object.
|
17
17
|
#
|
@@ -57,7 +57,10 @@ module Mongoid
|
|
57
57
|
def push(pushes)
|
58
58
|
prepare_atomic_operation do |ops|
|
59
59
|
process_atomic_operations(pushes) do |field, value|
|
60
|
-
existing = send(field) ||
|
60
|
+
existing = send(field) || begin
|
61
|
+
attributes[field] ||= []
|
62
|
+
attributes[field]
|
63
|
+
end
|
61
64
|
values = [ value ].flatten(1)
|
62
65
|
values.each{ |val| existing.push(val) }
|
63
66
|
ops[atomic_attribute_name(field)] = { "$each" => values }
|
@@ -122,6 +122,12 @@ module Mongoid
|
|
122
122
|
end
|
123
123
|
end
|
124
124
|
|
125
|
+
def client_name
|
126
|
+
@client_name ||= options[:client] ||
|
127
|
+
Threaded.client_override ||
|
128
|
+
storage_options && __evaluate__(storage_options[:client])
|
129
|
+
end
|
130
|
+
|
125
131
|
# Determine if this persistence context is equal to another.
|
126
132
|
#
|
127
133
|
# @example Compare two persistence contexts.
|
@@ -139,12 +145,6 @@ module Mongoid
|
|
139
145
|
|
140
146
|
private
|
141
147
|
|
142
|
-
def client_name
|
143
|
-
@client_name ||= options[:client] ||
|
144
|
-
Threaded.client_override ||
|
145
|
-
storage_options && __evaluate__(storage_options[:client])
|
146
|
-
end
|
147
|
-
|
148
148
|
def set_options!(opts)
|
149
149
|
@options ||= opts.each.reduce({}) do |_options, (key, value)|
|
150
150
|
unless VALID_OPTIONS.include?(key.to_sym)
|
data/lib/mongoid/query_cache.rb
CHANGED
@@ -168,7 +168,8 @@ module Mongoid
|
|
168
168
|
@coll_name ||= result.namespace.sub("#{database.name}.", '') if result.namespace
|
169
169
|
documents = result.documents
|
170
170
|
if @cursor_id.zero? && !@after_first_batch
|
171
|
-
|
171
|
+
@cached_documents ||= []
|
172
|
+
@cached_documents.concat(documents)
|
172
173
|
end
|
173
174
|
@after_first_batch = true
|
174
175
|
documents
|
@@ -150,7 +150,7 @@ module Mongoid
|
|
150
150
|
#
|
151
151
|
# @since 2.3.0
|
152
152
|
def filter(value)
|
153
|
-
!case_sensitive? && value ? /\A#{Regexp.escape(value.to_s)}
|
153
|
+
!case_sensitive? && value ? /\A#{Regexp.escape(value.to_s)}\z/i : value
|
154
154
|
end
|
155
155
|
|
156
156
|
# Scope the criteria to the scope options provided.
|
data/lib/mongoid/version.rb
CHANGED
@@ -13,7 +13,7 @@ class <%= class_name %><%= " < #{options[:parent].classify}" if options[:parent]
|
|
13
13
|
field :<%= attribute.name %>, type: <%= attribute.type_class %>
|
14
14
|
<% end -%>
|
15
15
|
<% attributes.select{|attr| attr.reference? }.each do |attribute| -%>
|
16
|
-
|
16
|
+
belongs_to :<%= attribute.name%>
|
17
17
|
<% end -%>
|
18
18
|
end
|
19
19
|
<% end -%>
|