mongoid 7.2.1 → 7.3.1
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/README.md +1 -1
- data/Rakefile +16 -0
- data/lib/config/locales/en.yml +2 -2
- data/lib/mongoid/association/accessors.rb +13 -1
- data/lib/mongoid/association/constrainable.rb +1 -1
- data/lib/mongoid/association/depending.rb +4 -4
- data/lib/mongoid/association/embedded/batchable.rb +1 -1
- data/lib/mongoid/association/embedded/embedded_in.rb +1 -1
- data/lib/mongoid/association/embedded/embeds_many/proxy.rb +10 -3
- data/lib/mongoid/association/nested/many.rb +1 -1
- data/lib/mongoid/association/nested/one.rb +4 -2
- data/lib/mongoid/association/proxy.rb +6 -1
- data/lib/mongoid/association/referenced/auto_save.rb +2 -2
- data/lib/mongoid/association/referenced/has_many/enumerable.rb +493 -495
- data/lib/mongoid/association/referenced/has_many/proxy.rb +2 -2
- data/lib/mongoid/association/referenced/has_one/nested_builder.rb +2 -2
- data/lib/mongoid/attributes.rb +32 -14
- data/lib/mongoid/attributes/projector.rb +120 -0
- data/lib/mongoid/cacheable.rb +2 -2
- data/lib/mongoid/clients.rb +1 -1
- data/lib/mongoid/clients/factory.rb +22 -8
- data/lib/mongoid/config.rb +19 -2
- data/lib/mongoid/contextual/aggregable/mongo.rb +10 -8
- data/lib/mongoid/copyable.rb +1 -1
- data/lib/mongoid/criteria.rb +4 -5
- data/lib/mongoid/criteria/findable.rb +1 -1
- data/lib/mongoid/criteria/queryable/expandable.rb +0 -24
- data/lib/mongoid/criteria/queryable/extensions.rb +0 -4
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +1 -1
- data/lib/mongoid/criteria/queryable/mergeable.rb +46 -20
- data/lib/mongoid/criteria/queryable/selectable.rb +8 -8
- data/lib/mongoid/document.rb +1 -15
- data/lib/mongoid/errors/delete_restriction.rb +8 -9
- data/lib/mongoid/errors/mongoid_error.rb +1 -1
- data/lib/mongoid/evolvable.rb +1 -1
- data/lib/mongoid/extensions/boolean.rb +1 -2
- data/lib/mongoid/extensions/false_class.rb +1 -1
- data/lib/mongoid/extensions/hash.rb +2 -2
- data/lib/mongoid/extensions/true_class.rb +1 -1
- data/lib/mongoid/fields.rb +43 -5
- data/lib/mongoid/inspectable.rb +1 -1
- data/lib/mongoid/matcher.rb +26 -43
- data/lib/mongoid/matcher/bits.rb +41 -0
- data/lib/mongoid/matcher/bits_all_clear.rb +20 -0
- data/lib/mongoid/matcher/bits_all_set.rb +20 -0
- data/lib/mongoid/matcher/bits_any_clear.rb +20 -0
- data/lib/mongoid/matcher/bits_any_set.rb +20 -0
- data/lib/mongoid/matcher/elem_match.rb +2 -1
- data/lib/mongoid/matcher/expression.rb +9 -14
- data/lib/mongoid/matcher/field_expression.rb +4 -5
- data/lib/mongoid/matcher/field_operator.rb +6 -0
- data/lib/mongoid/matcher/mod.rb +17 -0
- data/lib/mongoid/matcher/type.rb +99 -0
- data/lib/mongoid/persistable/deletable.rb +1 -2
- data/lib/mongoid/persistable/destroyable.rb +8 -2
- data/lib/mongoid/persistable/updatable.rb +27 -2
- data/lib/mongoid/query_cache.rb +35 -29
- data/lib/mongoid/reloadable.rb +5 -0
- data/lib/mongoid/selectable.rb +5 -7
- data/lib/mongoid/shardable.rb +21 -5
- data/lib/mongoid/touchable.rb +23 -4
- data/lib/mongoid/validatable/associated.rb +1 -1
- data/lib/mongoid/validatable/presence.rb +3 -3
- data/lib/mongoid/validatable/uniqueness.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/rails/generators/mongoid/config/config_generator.rb +8 -1
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +1 -1
- data/spec/integration/app_spec.rb +139 -82
- data/spec/integration/associations/embeds_many_spec.rb +44 -0
- data/spec/integration/associations/has_one_spec.rb +48 -0
- data/spec/integration/criteria/date_field_spec.rb +1 -1
- data/spec/integration/document_spec.rb +30 -0
- data/spec/integration/matcher_operator_data/bits_all_clear.yml +159 -0
- data/spec/integration/matcher_operator_data/bits_all_set.yml +159 -0
- data/spec/integration/matcher_operator_data/bits_any_clear.yml +159 -0
- data/spec/integration/matcher_operator_data/bits_any_set.yml +159 -0
- data/spec/integration/matcher_operator_data/comment.yml +22 -0
- data/spec/integration/matcher_operator_data/elem_match.yml +46 -0
- data/spec/integration/matcher_operator_data/implicit_traversal.yml +96 -0
- data/spec/integration/matcher_operator_data/in.yml +16 -0
- data/spec/integration/matcher_operator_data/mod.yml +55 -0
- data/spec/integration/matcher_operator_data/type.yml +70 -0
- data/spec/integration/matcher_operator_data/type_array.yml +16 -0
- data/spec/integration/matcher_operator_data/type_binary.yml +18 -0
- data/spec/integration/matcher_operator_data/type_boolean.yml +39 -0
- data/spec/integration/matcher_operator_data/type_code.yml +26 -0
- data/spec/integration/matcher_operator_data/type_code_with_scope.yml +26 -0
- data/spec/integration/matcher_operator_data/type_date.yml +39 -0
- data/spec/integration/matcher_operator_data/type_db_pointer.yml +19 -0
- data/spec/integration/matcher_operator_data/type_decimal.yml +40 -0
- data/spec/integration/matcher_operator_data/type_double.yml +15 -0
- data/spec/integration/matcher_operator_data/type_int32.yml +33 -0
- data/spec/integration/matcher_operator_data/type_int64.yml +33 -0
- data/spec/integration/matcher_operator_data/type_max_key.yml +17 -0
- data/spec/integration/matcher_operator_data/type_min_key.yml +17 -0
- data/spec/integration/matcher_operator_data/type_null.yml +23 -0
- data/spec/integration/matcher_operator_data/type_object.yml +23 -0
- data/spec/integration/matcher_operator_data/type_object_id.yml +25 -0
- data/spec/integration/matcher_operator_data/type_regex.yml +44 -0
- data/spec/integration/matcher_operator_data/type_string.yml +15 -0
- data/spec/integration/matcher_operator_data/type_symbol.yml +32 -0
- data/spec/integration/matcher_operator_data/type_timestamp.yml +25 -0
- data/spec/integration/matcher_operator_data/type_undefined.yml +17 -0
- data/spec/lite_spec_helper.rb +4 -3
- data/spec/mongoid/association/depending_spec.rb +391 -352
- data/spec/mongoid/association/nested/one_spec.rb +18 -14
- data/spec/mongoid/association/referenced/belongs_to/proxy_spec.rb +25 -8
- data/spec/mongoid/association/referenced/has_and_belongs_to_many/binding_spec.rb +1 -1
- data/spec/mongoid/association/referenced/has_many/binding_spec.rb +1 -1
- data/spec/mongoid/association/referenced/has_many/enumerable_spec.rb +1 -1
- data/spec/mongoid/association/referenced/has_one_models.rb +8 -0
- data/spec/mongoid/atomic/paths_spec.rb +64 -12
- data/spec/mongoid/attributes/projector_data/embedded.yml +105 -0
- data/spec/mongoid/attributes/projector_data/fields.yml +93 -0
- data/spec/mongoid/attributes/projector_spec.rb +41 -0
- data/spec/mongoid/attributes_spec.rb +333 -0
- data/spec/mongoid/clients/factory_spec.rb +48 -0
- data/spec/mongoid/config_spec.rb +32 -0
- data/spec/mongoid/contextual/atomic_spec.rb +17 -4
- data/spec/mongoid/contextual/mongo_spec.rb +2 -2
- data/spec/mongoid/criteria/modifiable_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/expandable_spec.rb +0 -73
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +1 -1
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +105 -7
- data/spec/mongoid/criteria/queryable/selectable_logical_spec.rb +229 -24
- data/spec/mongoid/criteria/queryable/selectable_shared_examples.rb +39 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +1 -565
- data/spec/mongoid/criteria/queryable/selectable_where_spec.rb +590 -0
- data/spec/mongoid/criteria_projection_spec.rb +411 -0
- data/spec/mongoid/criteria_spec.rb +0 -275
- data/spec/mongoid/document_fields_spec.rb +26 -0
- data/spec/mongoid/document_query_spec.rb +51 -0
- data/spec/mongoid/document_spec.rb +13 -13
- data/spec/mongoid/errors/delete_restriction_spec.rb +1 -1
- data/spec/mongoid/errors/mongoid_error_spec.rb +20 -8
- data/spec/mongoid/extensions/false_class_spec.rb +1 -1
- data/spec/mongoid/extensions/string_spec.rb +5 -5
- data/spec/mongoid/extensions/true_class_spec.rb +1 -1
- data/spec/mongoid/fields/localized_spec.rb +4 -4
- data/spec/mongoid/fields_spec.rb +4 -4
- data/spec/mongoid/inspectable_spec.rb +12 -4
- data/spec/mongoid/matcher/extract_attribute_data/numeric_keys.yml +104 -0
- data/spec/mongoid/matcher/extract_attribute_data/traversal.yml +68 -88
- data/spec/mongoid/matcher/extract_attribute_spec.rb +3 -13
- data/spec/mongoid/persistable/deletable_spec.rb +175 -1
- data/spec/mongoid/persistable/destroyable_spec.rb +191 -3
- data/spec/mongoid/persistable/savable_spec.rb +3 -5
- data/spec/mongoid/persistable/settable_spec.rb +30 -0
- data/spec/mongoid/persistable/upsertable_spec.rb +1 -1
- data/spec/mongoid/persistable_spec.rb +2 -2
- data/spec/mongoid/query_cache_middleware_spec.rb +8 -0
- data/spec/mongoid/reloadable_spec.rb +18 -1
- data/spec/mongoid/shardable_spec.rb +44 -0
- data/spec/mongoid/touchable_spec.rb +104 -16
- data/spec/mongoid/touchable_spec_models.rb +52 -0
- data/spec/mongoid/validatable_spec.rb +1 -1
- data/spec/shared/bin/get-mongodb-download-url +17 -0
- data/spec/shared/bin/s3-copy +45 -0
- data/spec/shared/bin/s3-upload +69 -0
- data/spec/shared/lib/mrss/cluster_config.rb +19 -4
- data/spec/shared/lib/mrss/constraints.rb +46 -8
- data/spec/shared/lib/mrss/docker_runner.rb +10 -1
- data/spec/shared/lib/mrss/lite_constraints.rb +16 -0
- data/spec/shared/lib/mrss/server_version_registry.rb +79 -33
- data/spec/shared/lib/mrss/spec_organizer.rb +32 -2
- data/spec/shared/lib/mrss/utils.rb +15 -0
- data/spec/shared/share/Dockerfile.erb +122 -29
- data/spec/shared/share/haproxy-1.conf +16 -0
- data/spec/shared/share/haproxy-2.conf +17 -0
- data/spec/shared/shlib/server.sh +58 -11
- data/spec/shared/shlib/set_env.sh +4 -1
- data/spec/spec_helper.rb +7 -3
- data/spec/support/client_registry.rb +9 -0
- data/spec/support/models/bolt.rb +8 -0
- data/spec/support/models/hole.rb +13 -0
- data/spec/support/models/mop.rb +9 -0
- data/spec/support/models/nut.rb +8 -0
- data/spec/support/models/person.rb +6 -0
- data/spec/support/models/sealer.rb +8 -0
- data/spec/support/models/shirt.rb +12 -0
- data/spec/support/models/spacer.rb +8 -0
- data/spec/support/models/threadlocker.rb +8 -0
- data/spec/support/models/washer.rb +8 -0
- data/spec/support/spec_config.rb +8 -0
- metadata +636 -528
- metadata.gz.sig +0 -0
- data/spec/support/cluster_config.rb +0 -158
|
@@ -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
|
|
@@ -15,7 +15,8 @@ module Mongoid
|
|
|
15
15
|
# Validate the condition is valid, even though we will never attempt
|
|
16
16
|
# matching it.
|
|
17
17
|
condition.each do |k, v|
|
|
18
|
-
|
|
18
|
+
k = k.to_s
|
|
19
|
+
if k.start_with?('$')
|
|
19
20
|
begin
|
|
20
21
|
ExpressionOperator.get(k)
|
|
21
22
|
rescue Mongoid::Errors::InvalidExpressionOperator
|
|
@@ -12,25 +12,20 @@ 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
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
# Do not treat a hash as an array here (both are iterable).
|
|
23
|
-
if expanded && Array === value
|
|
24
|
-
if value == []
|
|
25
|
-
# Empty array is technically equivalent to exists: false.
|
|
26
|
-
FieldExpression.matches?(false, nil, expr_v)
|
|
27
|
-
else
|
|
28
|
-
value.any? do |v|
|
|
29
|
-
FieldExpression.matches?(true, v, expr_v)
|
|
30
|
-
end
|
|
22
|
+
values = Matcher.extract_attribute(document, k)
|
|
23
|
+
if values.length > 0
|
|
24
|
+
values.any? do |v|
|
|
25
|
+
FieldExpression.matches?(true, v, expr_v)
|
|
31
26
|
end
|
|
32
27
|
else
|
|
33
|
-
FieldExpression.matches?(
|
|
28
|
+
FieldExpression.matches?(false, nil, expr_v)
|
|
34
29
|
end
|
|
35
30
|
end
|
|
36
31
|
end
|
|
@@ -36,14 +36,13 @@ module Mongoid
|
|
|
36
36
|
FieldOperator.get(k).matches?(exists, value, cond_v)
|
|
37
37
|
end
|
|
38
38
|
elsif Hash === value
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
sub_value.any? do |sub_v|
|
|
39
|
+
sub_values = Matcher.extract_attribute(value, k)
|
|
40
|
+
if sub_values.length > 0
|
|
41
|
+
sub_values.any? do |sub_v|
|
|
43
42
|
Eq.matches?(true, sub_v, cond_v)
|
|
44
43
|
end
|
|
45
44
|
else
|
|
46
|
-
Eq.matches?(
|
|
45
|
+
Eq.matches?(false, nil, cond_v)
|
|
47
46
|
end
|
|
48
47
|
else
|
|
49
48
|
false
|
|
@@ -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
|
|
@@ -47,7 +47,7 @@ module Mongoid
|
|
|
47
47
|
#
|
|
48
48
|
# @since 4.0.0
|
|
49
49
|
def atomic_deletes
|
|
50
|
-
{ atomic_delete_modifier => { atomic_path => _index ? { "_id" =>
|
|
50
|
+
{ atomic_delete_modifier => { atomic_path => _index ? { "_id" => _id } : true }}
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
# Delete the embedded document.
|
|
@@ -117,7 +117,6 @@ module Mongoid
|
|
|
117
117
|
#
|
|
118
118
|
# @since 4.0.0
|
|
119
119
|
def prepare_delete
|
|
120
|
-
return false unless catch(:abort) { apply_delete_dependencies! }
|
|
121
120
|
yield(self)
|
|
122
121
|
freeze
|
|
123
122
|
self.destroyed = true
|
|
@@ -23,13 +23,19 @@ module Mongoid
|
|
|
23
23
|
def destroy(options = nil)
|
|
24
24
|
raise Errors::ReadonlyDocument.new(self.class) if readonly?
|
|
25
25
|
self.flagged_for_destroy = true
|
|
26
|
-
result = run_callbacks(:destroy)
|
|
26
|
+
result = run_callbacks(:destroy) do
|
|
27
|
+
if catch(:abort) { apply_destroy_dependencies! }
|
|
28
|
+
delete(options || {})
|
|
29
|
+
else
|
|
30
|
+
false
|
|
31
|
+
end
|
|
32
|
+
end
|
|
27
33
|
self.flagged_for_destroy = false
|
|
28
34
|
result
|
|
29
35
|
end
|
|
30
36
|
|
|
31
37
|
def destroy!(options = {})
|
|
32
|
-
destroy || raise(Errors::DocumentNotDestroyed.new(
|
|
38
|
+
destroy || raise(Errors::DocumentNotDestroyed.new(_id, self.class))
|
|
33
39
|
end
|
|
34
40
|
|
|
35
41
|
module ClassMethods
|
|
@@ -137,8 +137,33 @@ module Mongoid
|
|
|
137
137
|
coll = collection(_root)
|
|
138
138
|
selector = atomic_selector
|
|
139
139
|
coll.find(selector).update_one(positionally(selector, updates), session: _session)
|
|
140
|
-
|
|
141
|
-
|
|
140
|
+
|
|
141
|
+
# The following code applies updates which would cause
|
|
142
|
+
# path conflicts in MongoDB, for example when changing attributes
|
|
143
|
+
# of foo.0.bars while adding another foo. Each conflicting update
|
|
144
|
+
# is applied using its own write.
|
|
145
|
+
#
|
|
146
|
+
# TODO: MONGOID-5026: reduce the number of writes performed by
|
|
147
|
+
# more intelligently combining the writes such that there are
|
|
148
|
+
# fewer conflicts.
|
|
149
|
+
conflicts.each_pair do |modifier, changes|
|
|
150
|
+
|
|
151
|
+
# Group the changes according to their root key which is
|
|
152
|
+
# the top-level association name.
|
|
153
|
+
# This handles at least the cases described in MONGOID-4982.
|
|
154
|
+
conflicting_change_groups = changes.group_by do |key, _|
|
|
155
|
+
key.split(".", 2).first
|
|
156
|
+
end.values
|
|
157
|
+
|
|
158
|
+
# Apply changes in batches. Pop one change from each
|
|
159
|
+
# field-conflict group round-robin until all changes
|
|
160
|
+
# have been applied.
|
|
161
|
+
while batched_changes = conflicting_change_groups.map(&:pop).compact.to_h.presence
|
|
162
|
+
coll.find(selector).update_one(
|
|
163
|
+
positionally(selector, modifier => batched_changes),
|
|
164
|
+
session: _session,
|
|
165
|
+
)
|
|
166
|
+
end
|
|
142
167
|
end
|
|
143
168
|
end
|
|
144
169
|
end
|
data/lib/mongoid/query_cache.rb
CHANGED
|
@@ -117,38 +117,44 @@ module Mongoid
|
|
|
117
117
|
end
|
|
118
118
|
end
|
|
119
119
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
# Instantiate the middleware.
|
|
127
|
-
#
|
|
128
|
-
# @example Create the new middleware.
|
|
129
|
-
# Middleware.new(app)
|
|
130
|
-
#
|
|
131
|
-
# @param [ Object ] app The rack applciation stack.
|
|
120
|
+
if defined?(Mongo::QueryCache::Middleware)
|
|
121
|
+
Middleware = Mongo::QueryCache::Middleware
|
|
122
|
+
else
|
|
123
|
+
# The middleware to be added to a rack application in order to activate the
|
|
124
|
+
# query cache.
|
|
132
125
|
#
|
|
133
126
|
# @since 4.0.0
|
|
134
|
-
|
|
135
|
-
@app = app
|
|
136
|
-
end
|
|
127
|
+
class Middleware
|
|
137
128
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
129
|
+
# Instantiate the middleware.
|
|
130
|
+
#
|
|
131
|
+
# @example Create the new middleware.
|
|
132
|
+
# Middleware.new(app)
|
|
133
|
+
#
|
|
134
|
+
# @param [ Object ] app The rack application stack.
|
|
135
|
+
#
|
|
136
|
+
# @since 4.0.0
|
|
137
|
+
def initialize(app)
|
|
138
|
+
@app = app
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Execute the request, wrapping in a query cache.
|
|
142
|
+
#
|
|
143
|
+
# @example Execute the request.
|
|
144
|
+
# middleware.call(env)
|
|
145
|
+
#
|
|
146
|
+
# @param [ Object ] env The environment.
|
|
147
|
+
#
|
|
148
|
+
# @return [ Object ] The result of the call.
|
|
149
|
+
#
|
|
150
|
+
# @since 4.0.0
|
|
151
|
+
def call(env)
|
|
152
|
+
QueryCache.cache do
|
|
153
|
+
@app.call(env)
|
|
154
|
+
end
|
|
155
|
+
ensure
|
|
156
|
+
QueryCache.clear_cache
|
|
157
|
+
end
|
|
152
158
|
end
|
|
153
159
|
end
|
|
154
160
|
|