mongoid 5.4.0 → 6.4.8
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/README.md +3 -3
- data/Rakefile +26 -0
- data/lib/config/locales/en.yml +40 -0
- data/lib/mongoid/atomic/modifiers.rb +2 -2
- data/lib/mongoid/atomic.rb +5 -5
- data/lib/mongoid/attributes/readonly.rb +22 -0
- data/lib/mongoid/attributes.rb +22 -21
- data/lib/mongoid/cacheable.rb +36 -0
- data/lib/mongoid/changeable.rb +36 -0
- data/lib/mongoid/clients/options.rb +55 -250
- data/lib/mongoid/clients/sessions.rb +113 -0
- data/lib/mongoid/clients/storage_options.rb +2 -69
- data/lib/mongoid/clients.rb +10 -63
- data/lib/mongoid/composable.rb +29 -2
- data/lib/mongoid/config.rb +1 -0
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/atomic.rb +4 -4
- data/lib/mongoid/contextual/map_reduce.rb +7 -3
- data/lib/mongoid/contextual/memory.rb +9 -4
- data/lib/mongoid/contextual/mongo.rb +65 -30
- data/lib/mongoid/contextual/none.rb +12 -0
- data/lib/mongoid/copyable.rb +13 -6
- data/lib/mongoid/criteria/marshalable.rb +2 -2
- data/lib/mongoid/criteria/modifiable.rb +29 -3
- data/lib/mongoid/criteria/options.rb +25 -0
- data/lib/mongoid/criteria/queryable/aggregable.rb +120 -0
- data/lib/mongoid/criteria/queryable/extensions/array.rb +185 -0
- data/lib/mongoid/criteria/queryable/extensions/big_decimal.rb +37 -0
- data/lib/mongoid/criteria/queryable/extensions/boolean.rb +34 -0
- data/lib/mongoid/criteria/queryable/extensions/date.rb +63 -0
- data/lib/mongoid/criteria/queryable/extensions/date_time.rb +53 -0
- data/lib/mongoid/criteria/queryable/extensions/hash.rb +200 -0
- data/lib/mongoid/criteria/queryable/extensions/nil_class.rb +86 -0
- data/lib/mongoid/criteria/queryable/extensions/numeric.rb +90 -0
- data/lib/mongoid/criteria/queryable/extensions/object.rb +206 -0
- data/lib/mongoid/criteria/queryable/extensions/range.rb +70 -0
- data/lib/mongoid/criteria/queryable/extensions/regexp.rb +79 -0
- data/lib/mongoid/criteria/queryable/extensions/set.rb +34 -0
- data/lib/mongoid/criteria/queryable/extensions/string.rb +137 -0
- data/lib/mongoid/criteria/queryable/extensions/symbol.rb +79 -0
- data/lib/mongoid/criteria/queryable/extensions/time.rb +60 -0
- data/lib/mongoid/criteria/queryable/extensions/time_with_zone.rb +54 -0
- data/lib/mongoid/criteria/queryable/extensions.rb +28 -0
- data/lib/mongoid/criteria/queryable/forwardable.rb +65 -0
- data/lib/mongoid/criteria/queryable/key.rb +103 -0
- data/lib/mongoid/criteria/queryable/macroable.rb +27 -0
- data/lib/mongoid/criteria/queryable/mergeable.rb +273 -0
- data/lib/mongoid/criteria/queryable/optional.rb +429 -0
- data/lib/mongoid/criteria/queryable/options.rb +153 -0
- data/lib/mongoid/criteria/queryable/pipeline.rb +111 -0
- data/lib/mongoid/criteria/queryable/selectable.rb +689 -0
- data/lib/mongoid/criteria/queryable/selector.rb +212 -0
- data/lib/mongoid/criteria/queryable/smash.rb +104 -0
- data/lib/mongoid/criteria/queryable.rb +87 -0
- data/lib/mongoid/criteria.rb +6 -2
- data/lib/mongoid/document.rb +34 -41
- data/lib/mongoid/errors/ambiguous_relationship.rb +1 -1
- data/lib/mongoid/errors/in_memory_collation_not_supported.rb +1 -1
- data/lib/mongoid/errors/invalid_field.rb +2 -2
- data/lib/mongoid/errors/invalid_persistence_option.rb +29 -0
- data/lib/mongoid/errors/invalid_relation.rb +66 -0
- data/lib/mongoid/errors/invalid_session_use.rb +24 -0
- data/lib/mongoid/errors.rb +3 -0
- data/lib/mongoid/evolvable.rb +1 -1
- data/lib/mongoid/extensions/big_decimal.rb +17 -8
- data/lib/mongoid/extensions/date.rb +4 -1
- data/lib/mongoid/extensions/decimal128.rb +3 -3
- data/lib/mongoid/extensions/hash.rb +1 -0
- data/lib/mongoid/extensions/regexp.rb +1 -0
- data/lib/mongoid/extensions/string.rb +6 -3
- data/lib/mongoid/extensions/time.rb +4 -1
- data/lib/mongoid/extensions.rb +0 -4
- data/lib/mongoid/factory.rb +2 -1
- data/lib/mongoid/fields/validators/macro.rb +18 -0
- data/lib/mongoid/findable.rb +2 -2
- data/lib/mongoid/indexable.rb +16 -14
- data/lib/mongoid/interceptable.rb +9 -22
- data/lib/mongoid/matchable/all.rb +2 -2
- data/lib/mongoid/matchable/and.rb +3 -3
- data/lib/mongoid/matchable/default.rb +2 -2
- data/lib/mongoid/matchable/elem_match.rb +28 -0
- data/lib/mongoid/matchable/exists.rb +2 -2
- data/lib/mongoid/matchable/gt.rb +4 -2
- data/lib/mongoid/matchable/gte.rb +4 -2
- data/lib/mongoid/matchable/in.rb +2 -2
- data/lib/mongoid/matchable/lt.rb +4 -2
- data/lib/mongoid/matchable/lte.rb +4 -2
- data/lib/mongoid/matchable/ne.rb +2 -2
- data/lib/mongoid/matchable/nin.rb +2 -2
- data/lib/mongoid/matchable/nor.rb +37 -0
- data/lib/mongoid/matchable/or.rb +3 -3
- data/lib/mongoid/matchable/regexp.rb +3 -3
- data/lib/mongoid/matchable/size.rb +2 -2
- data/lib/mongoid/matchable.rb +16 -7
- data/lib/mongoid/persistable/creatable.rb +5 -3
- data/lib/mongoid/persistable/deletable.rb +5 -3
- data/lib/mongoid/persistable/destroyable.rb +1 -5
- data/lib/mongoid/persistable/settable.rb +5 -5
- data/lib/mongoid/persistable/updatable.rb +7 -14
- data/lib/mongoid/persistable/upsertable.rb +2 -1
- data/lib/mongoid/persistable.rb +4 -6
- data/lib/mongoid/persistence_context.rb +220 -0
- data/lib/mongoid/query_cache.rb +67 -23
- data/lib/mongoid/railtie.rb +17 -1
- data/lib/mongoid/railties/controller_runtime.rb +86 -0
- data/lib/mongoid/relations/accessors.rb +3 -0
- data/lib/mongoid/relations/auto_save.rb +12 -4
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +4 -4
- data/lib/mongoid/relations/counter_cache.rb +15 -5
- data/lib/mongoid/relations/eager/base.rb +3 -3
- data/lib/mongoid/relations/eager/has_and_belongs_to_many.rb +2 -2
- data/lib/mongoid/relations/eager/has_many.rb +1 -1
- data/lib/mongoid/relations/eager.rb +6 -11
- data/lib/mongoid/relations/embedded/batchable.rb +20 -18
- data/lib/mongoid/relations/embedded/in.rb +13 -1
- data/lib/mongoid/relations/embedded/many.rb +51 -10
- data/lib/mongoid/relations/embedded/one.rb +14 -1
- data/lib/mongoid/relations/macros.rb +9 -1
- data/lib/mongoid/relations/many.rb +4 -0
- data/lib/mongoid/relations/metadata.rb +3 -3
- data/lib/mongoid/relations/options.rb +2 -2
- data/lib/mongoid/relations/proxy.rb +1 -31
- data/lib/mongoid/relations/referenced/in.rb +19 -10
- data/lib/mongoid/relations/referenced/many.rb +30 -26
- data/lib/mongoid/relations/referenced/many_to_many.rb +20 -13
- data/lib/mongoid/relations/referenced/one.rb +15 -1
- data/lib/mongoid/relations/synchronization.rb +12 -12
- data/lib/mongoid/relations/targets/enumerable.rb +24 -4
- data/lib/mongoid/relations/touchable.rb +7 -4
- data/lib/mongoid/reloadable.rb +2 -2
- data/lib/mongoid/scopable.rb +3 -3
- data/lib/mongoid/serializable.rb +1 -1
- data/lib/mongoid/stateful.rb +1 -0
- data/lib/mongoid/tasks/database.rb +3 -2
- data/lib/mongoid/threaded.rb +74 -0
- data/lib/mongoid/traversable.rb +1 -1
- data/lib/mongoid/validatable/uniqueness.rb +1 -2
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid.rb +6 -6
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +18 -3
- data/spec/app/models/agent.rb +2 -0
- data/spec/app/models/album.rb +5 -1
- data/spec/app/models/array_field.rb +7 -0
- data/spec/app/models/artist.rb +21 -0
- data/spec/app/models/band.rb +3 -0
- data/spec/app/models/book.rb +2 -1
- data/spec/app/models/delegating_patient.rb +16 -0
- data/spec/app/models/dokument.rb +1 -0
- data/spec/app/models/ordered_post.rb +5 -0
- data/spec/app/models/oscar.rb +1 -2
- data/spec/app/models/page.rb +1 -1
- data/spec/app/models/person.rb +3 -3
- data/spec/app/models/princess.rb +2 -0
- data/spec/app/models/record.rb +1 -0
- data/spec/app/models/subscription.rb +1 -0
- data/spec/app/models/thing.rb +1 -1
- data/spec/config/mongoid.yml +15 -0
- data/spec/integration/document_spec.rb +22 -0
- data/spec/mongoid/atomic/modifiers_spec.rb +3 -3
- data/spec/mongoid/atomic_spec.rb +5 -5
- data/spec/mongoid/attributes/nested_spec.rb +18 -14
- data/spec/mongoid/attributes/readonly_spec.rb +87 -44
- data/spec/mongoid/attributes_spec.rb +90 -5
- data/spec/mongoid/cacheable_spec.rb +112 -0
- data/spec/mongoid/changeable_spec.rb +58 -0
- data/spec/mongoid/clients/factory_spec.rb +80 -28
- data/spec/mongoid/clients/options_spec.rb +396 -95
- data/spec/mongoid/clients/sessions_spec.rb +334 -0
- data/spec/mongoid/clients_spec.rb +243 -101
- data/spec/mongoid/composable_spec.rb +7 -0
- data/spec/mongoid/config_spec.rb +67 -11
- data/spec/mongoid/contextual/atomic_spec.rb +3 -3
- data/spec/mongoid/contextual/geo_near_spec.rb +1 -0
- data/spec/mongoid/contextual/mongo_spec.rb +275 -22
- data/spec/mongoid/contextual/none_spec.rb +15 -0
- data/spec/mongoid/copyable_spec.rb +13 -4
- data/spec/mongoid/criteria/modifiable_spec.rb +297 -16
- data/spec/mongoid/criteria/options_spec.rb +29 -0
- data/spec/mongoid/criteria/queryable/aggregable_spec.rb +370 -0
- data/spec/mongoid/criteria/queryable/extensions/array_spec.rb +523 -0
- data/spec/mongoid/criteria/queryable/extensions/big_decimal_spec.rb +59 -0
- data/spec/mongoid/criteria/queryable/extensions/bignum_spec.rb +58 -0
- data/spec/mongoid/criteria/queryable/extensions/boolean_spec.rb +213 -0
- data/spec/mongoid/criteria/queryable/extensions/date_spec.rb +330 -0
- data/spec/mongoid/criteria/queryable/extensions/date_time_spec.rb +405 -0
- data/spec/mongoid/criteria/queryable/extensions/fixnum_spec.rb +58 -0
- data/spec/mongoid/criteria/queryable/extensions/float_spec.rb +65 -0
- data/spec/mongoid/criteria/queryable/extensions/hash_spec.rb +327 -0
- data/spec/mongoid/criteria/queryable/extensions/integer_spec.rb +65 -0
- data/spec/mongoid/criteria/queryable/extensions/nil_class_spec.rb +77 -0
- data/spec/mongoid/criteria/queryable/extensions/object_spec.rb +108 -0
- data/spec/mongoid/criteria/queryable/extensions/range_spec.rb +309 -0
- data/spec/mongoid/{extensions/origin → criteria/queryable/extensions}/regexp_raw_spec.rb +2 -2
- data/spec/mongoid/criteria/queryable/extensions/regexp_spec.rb +90 -0
- data/spec/mongoid/criteria/queryable/extensions/set_spec.rb +39 -0
- data/spec/mongoid/criteria/queryable/extensions/string_spec.rb +302 -0
- data/spec/mongoid/criteria/queryable/extensions/symbol_spec.rb +167 -0
- data/spec/mongoid/criteria/queryable/extensions/time_spec.rb +376 -0
- data/spec/mongoid/criteria/queryable/extensions/time_with_zone_spec.rb +347 -0
- data/spec/mongoid/criteria/queryable/forwardable_spec.rb +87 -0
- data/spec/mongoid/criteria/queryable/key_spec.rb +52 -0
- data/spec/mongoid/criteria/queryable/mergeable_spec.rb +49 -0
- data/spec/mongoid/criteria/queryable/optional_spec.rb +1799 -0
- data/spec/mongoid/criteria/queryable/options_spec.rb +360 -0
- data/spec/mongoid/criteria/queryable/pipeline_spec.rb +200 -0
- data/spec/mongoid/criteria/queryable/queryable_spec.rb +137 -0
- data/spec/mongoid/criteria/queryable/selectable_spec.rb +4242 -0
- data/spec/mongoid/criteria/queryable/selector_spec.rb +844 -0
- data/spec/mongoid/criteria/queryable/smash_spec.rb +30 -0
- data/spec/mongoid/criteria/scopable_spec.rb +81 -0
- data/spec/mongoid/criteria_spec.rb +156 -22
- data/spec/mongoid/document_spec.rb +100 -90
- data/spec/mongoid/errors/invalid_relation_spec.rb +37 -0
- data/spec/mongoid/errors/mongoid_error_spec.rb +6 -3
- data/spec/mongoid/extensions/big_decimal_spec.rb +321 -19
- data/spec/mongoid/extensions/boolean_spec.rb +14 -0
- data/spec/mongoid/extensions/date_spec.rb +2 -6
- data/spec/mongoid/extensions/date_time_spec.rb +2 -6
- data/spec/mongoid/extensions/decimal128_spec.rb +1 -1
- data/spec/mongoid/extensions/float_spec.rb +8 -1
- data/spec/mongoid/extensions/hash_spec.rb +15 -0
- data/spec/mongoid/extensions/integer_spec.rb +8 -1
- data/spec/mongoid/extensions/object_spec.rb +11 -0
- data/spec/mongoid/extensions/regexp_spec.rb +23 -0
- data/spec/mongoid/extensions/string_spec.rb +53 -4
- data/spec/mongoid/extensions/time_spec.rb +2 -6
- data/spec/mongoid/extensions/time_with_zone_spec.rb +2 -6
- data/spec/mongoid/factory_spec.rb +11 -0
- data/spec/mongoid/fields_spec.rb +1 -1
- data/spec/mongoid/findable_spec.rb +47 -2
- data/spec/mongoid/indexable_spec.rb +15 -3
- data/spec/mongoid/interceptable_spec.rb +85 -19
- data/spec/mongoid/matchable/all_spec.rb +4 -4
- data/spec/mongoid/matchable/and_spec.rb +10 -10
- data/spec/mongoid/matchable/default_spec.rb +12 -12
- data/spec/mongoid/matchable/elem_match_spec.rb +86 -0
- data/spec/mongoid/matchable/exists_spec.rb +5 -5
- data/spec/mongoid/matchable/gt_spec.rb +18 -7
- data/spec/mongoid/matchable/gte_spec.rb +17 -7
- data/spec/mongoid/matchable/in_spec.rb +5 -5
- data/spec/mongoid/matchable/lt_spec.rb +18 -7
- data/spec/mongoid/matchable/lte_spec.rb +18 -7
- data/spec/mongoid/matchable/ne_spec.rb +5 -5
- data/spec/mongoid/matchable/nin_spec.rb +5 -5
- data/spec/mongoid/matchable/nor_spec.rb +209 -0
- data/spec/mongoid/matchable/or_spec.rb +7 -7
- data/spec/mongoid/matchable/regexp_spec.rb +5 -5
- data/spec/mongoid/matchable/size_spec.rb +3 -3
- data/spec/mongoid/matchable_spec.rb +199 -54
- data/spec/mongoid/persistable/creatable_spec.rb +7 -2
- data/spec/mongoid/persistable/deletable_spec.rb +35 -1
- data/spec/mongoid/persistable/destroyable_spec.rb +25 -2
- data/spec/mongoid/persistable/incrementable_spec.rb +6 -6
- data/spec/mongoid/persistable/savable_spec.rb +34 -29
- data/spec/mongoid/persistable/settable_spec.rb +77 -27
- data/spec/mongoid/persistable/updatable_spec.rb +182 -3
- data/spec/mongoid/persistable_spec.rb +16 -16
- data/spec/mongoid/persistence_context_spec.rb +694 -0
- data/spec/mongoid/positional_spec.rb +1 -1
- data/spec/mongoid/query_cache_spec.rb +170 -12
- data/spec/mongoid/relations/accessors_spec.rb +1 -1
- data/spec/mongoid/relations/auto_save_spec.rb +39 -6
- data/spec/mongoid/relations/bindings/referenced/many_to_many_spec.rb +4 -4
- data/spec/mongoid/relations/builders_spec.rb +37 -10
- data/spec/mongoid/relations/counter_cache_spec.rb +64 -3
- data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +16 -0
- data/spec/mongoid/relations/eager_spec.rb +40 -0
- data/spec/mongoid/relations/embedded/many_spec.rb +305 -59
- data/spec/mongoid/relations/embedded/one_spec.rb +2 -1
- data/spec/mongoid/relations/macros_spec.rb +415 -7
- data/spec/mongoid/relations/metadata_spec.rb +15 -1
- data/spec/mongoid/relations/proxy_spec.rb +27 -1
- data/spec/mongoid/relations/referenced/in_spec.rb +41 -1
- data/spec/mongoid/relations/referenced/many_spec.rb +35 -25
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +14 -26
- data/spec/mongoid/relations/synchronization_spec.rb +48 -2
- data/spec/mongoid/relations/targets/enumerable_spec.rb +108 -0
- data/spec/mongoid/relations/touchable_spec.rb +40 -0
- data/spec/mongoid/reloadable_spec.rb +51 -0
- data/spec/mongoid/scopable_spec.rb +13 -0
- data/spec/mongoid/serializable_spec.rb +0 -50
- data/spec/mongoid/threaded_spec.rb +68 -0
- data/spec/mongoid/validatable/presence_spec.rb +1 -1
- data/spec/mongoid/validatable/uniqueness_spec.rb +18 -9
- data/spec/mongoid/validatable_spec.rb +16 -0
- data/spec/rails/controller_extension/controller_runtime_spec.rb +110 -0
- data/spec/spec_helper.rb +101 -8
- data/spec/support/cluster_config.rb +158 -0
- data/spec/support/constraints.rb +101 -0
- data/spec/support/macros.rb +20 -0
- data/spec/support/session_registry.rb +50 -0
- data/spec/support/spec_config.rb +42 -0
- data.tar.gz.sig +0 -0
- metadata +163 -61
- metadata.gz.sig +0 -0
- data/lib/mongoid/clients/thread_options.rb +0 -19
- data/lib/mongoid/extensions/origin/regexp_raw.rb +0 -43
- data/lib/mongoid/railties/document.rb +0 -12
- data/spec/mongoid/railties/document_spec.rb +0 -24
@@ -4,241 +4,85 @@ module Mongoid
|
|
4
4
|
module Options
|
5
5
|
extend ActiveSupport::Concern
|
6
6
|
|
7
|
-
#
|
8
|
-
# database or client.
|
7
|
+
# Change the persistence context for this object during the block.
|
9
8
|
#
|
10
9
|
# @example Save the current document to a different collection.
|
11
|
-
# model.with(collection: "secondary")
|
10
|
+
# model.with(collection: "secondary") do |m|
|
11
|
+
# m.save
|
12
|
+
# end
|
12
13
|
#
|
13
|
-
# @
|
14
|
-
#
|
15
|
-
#
|
16
|
-
# @example Save the current document to a different client.
|
17
|
-
# model.with(client: "replica_set").save
|
18
|
-
#
|
19
|
-
# @example Save with a combination of options.
|
20
|
-
# model.with(client: "sharded", database: "secondary").save
|
21
|
-
#
|
22
|
-
# @note This method will instantiate a new client under the covers and
|
23
|
-
# can be expensive. It is also recommended that the user manually
|
24
|
-
# closes the extra client after using it, otherwise an excessive amount
|
25
|
-
# of connections to the server will be eventually opened.
|
26
|
-
#
|
27
|
-
# @param [ Hash ] options The storage options.
|
14
|
+
# @param [ Hash, Mongoid::PersistenceContext ] options_or_context
|
15
|
+
# The storage options or a persistence context.
|
28
16
|
#
|
29
17
|
# @option options [ String, Symbol ] :collection The collection name.
|
30
18
|
# @option options [ String, Symbol ] :database The database name.
|
31
19
|
# @option options [ String, Symbol ] :client The client name.
|
32
20
|
#
|
33
|
-
# @
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
21
|
+
# @since 6.0.0
|
22
|
+
def with(options_or_context, &block)
|
23
|
+
original_cluster = persistence_context.cluster
|
24
|
+
set_persistence_context(options_or_context)
|
25
|
+
yield self
|
26
|
+
ensure
|
27
|
+
clear_persistence_context(original_cluster)
|
39
28
|
end
|
40
29
|
|
41
|
-
def
|
42
|
-
|
43
|
-
end
|
44
|
-
|
45
|
-
def mongo_client
|
46
|
-
tmp = persistence_options
|
47
|
-
if (opts = tmp && !tmp.empty? && tmp.dup)
|
48
|
-
if opts[:client]
|
49
|
-
client = Clients.with_name(opts[:client])
|
50
|
-
else
|
51
|
-
client = Clients.with_name(self.class.client_name)
|
52
|
-
client = client.use(self.class.database_name)
|
53
|
-
end
|
54
|
-
client.with(opts.reject{ |k, v| k == :collection || k == :client })
|
55
|
-
end
|
30
|
+
def collection(parent = nil)
|
31
|
+
persistence_context.collection(parent)
|
56
32
|
end
|
57
33
|
|
58
34
|
def collection_name
|
59
|
-
|
60
|
-
return v.to_sym
|
61
|
-
end
|
35
|
+
persistence_context.collection_name
|
62
36
|
end
|
63
37
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
# @return [ Hash ] The current persistence options.
|
74
|
-
#
|
75
|
-
# @since 4.0.0
|
76
|
-
def persistence_options(klass = self)
|
77
|
-
Thread.current["[mongoid][#{klass}]:persistence-options"]
|
78
|
-
end
|
79
|
-
|
80
|
-
# Get the client with special options for the current thread.
|
81
|
-
#
|
82
|
-
# @example Get the client with options.
|
83
|
-
# Threaded.client_with_options(Band)
|
84
|
-
#
|
85
|
-
# @param [ Class ] klass The model class.
|
86
|
-
#
|
87
|
-
# @return [ Mongo::Client ] The client.
|
88
|
-
#
|
89
|
-
# @since 5.1.0
|
90
|
-
def client_with_options(klass = self)
|
91
|
-
Thread.current["[mongoid][#{klass}]:mongo-client"]
|
92
|
-
end
|
93
|
-
|
94
|
-
private
|
95
|
-
# Set the persistence options on the current thread.
|
96
|
-
#
|
97
|
-
# @api private
|
98
|
-
#
|
99
|
-
# @example Set the persistence options.
|
100
|
-
# Threaded.set_persistence_options(Band, { write: { w: 3 }})
|
101
|
-
#
|
102
|
-
# @param [ Class ] klass The model class.
|
103
|
-
# @param [ Hash ] options The persistence options.
|
104
|
-
#
|
105
|
-
# @return [ Hash ] The persistence options.
|
106
|
-
#
|
107
|
-
# @since 4.0.0
|
108
|
-
def set_persistence_options(klass, options)
|
109
|
-
Thread.current["[mongoid][#{klass}]:persistence-options"] = options
|
110
|
-
end
|
111
|
-
|
112
|
-
# Unset the persistence options on the current thread.
|
113
|
-
#
|
114
|
-
# @api private
|
115
|
-
#
|
116
|
-
# @example Unset the persistence options.
|
117
|
-
# Threaded.unset_persistence_options(Band)
|
118
|
-
#
|
119
|
-
# @param [ Class ] klass The model class.
|
120
|
-
#
|
121
|
-
# @return [ nil ] nil.
|
122
|
-
#
|
123
|
-
# @since 5.1.0
|
124
|
-
def unset_persistence_options(klass)
|
125
|
-
Thread.current["[mongoid][#{klass}]:persistence-options"] = nil
|
126
|
-
end
|
127
|
-
|
128
|
-
# Set the persistence options and client with those options on the current thread.
|
129
|
-
# Note that a client will only be set if its cluster differs from the cluster of the
|
130
|
-
# original client.
|
131
|
-
#
|
132
|
-
# @api private
|
133
|
-
#
|
134
|
-
# @example Set the persistence options and client with those options on the current thread.
|
135
|
-
# Threaded.set_options(Band, { write: { w: 3 }})
|
136
|
-
#
|
137
|
-
# @param [ Class ] klass The model class.
|
138
|
-
# @param [ Mongo::Client ] options The options.
|
139
|
-
#
|
140
|
-
# @return [ Mongo::Client, nil ] The client or nil if the cluster does not change.
|
141
|
-
#
|
142
|
-
# @since 5.1.0
|
143
|
-
def set_options(klass, options)
|
144
|
-
original_cluster = mongo_client.cluster
|
145
|
-
set_persistence_options(klass, options)
|
146
|
-
m = mongo_client
|
147
|
-
set_client_with_options(klass, m) unless m.cluster.equal?(original_cluster)
|
148
|
-
end
|
38
|
+
def mongo_client
|
39
|
+
persistence_context.client
|
40
|
+
end
|
41
|
+
|
42
|
+
def persistence_context
|
43
|
+
PersistenceContext.get(self) ||
|
44
|
+
PersistenceContext.get(self.class) ||
|
45
|
+
PersistenceContext.new(self.class)
|
46
|
+
end
|
149
47
|
|
150
|
-
|
151
|
-
#
|
152
|
-
# @api private
|
153
|
-
#
|
154
|
-
# @example Set the client with options.
|
155
|
-
# Threaded.set_client_with_options(Band, client)
|
156
|
-
#
|
157
|
-
# @param [ Class ] klass The model class.
|
158
|
-
# @param [ Mongo::Client ] client The client with options.
|
159
|
-
#
|
160
|
-
# @return [ Mongo::Client ] The client.
|
161
|
-
#
|
162
|
-
# @since 5.1.0
|
163
|
-
def set_client_with_options(klass, client)
|
164
|
-
Thread.current["[mongoid][#{klass}]:mongo-client"] = client
|
165
|
-
end
|
48
|
+
private
|
166
49
|
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
#
|
171
|
-
# @example Unset the client with options.
|
172
|
-
# Threaded.unset_client_with_options(Band)
|
173
|
-
#
|
174
|
-
# @param [ Class ] klass The model class.
|
175
|
-
#
|
176
|
-
# @return [ nil ] nil.
|
177
|
-
#
|
178
|
-
# @since 5.1.0
|
179
|
-
def unset_client_with_options(klass)
|
180
|
-
if client = Thread.current["[mongoid][#{klass}]:mongo-client"]
|
181
|
-
client.close
|
182
|
-
Thread.current["[mongoid][#{klass}]:mongo-client"] = nil
|
183
|
-
end
|
184
|
-
end
|
50
|
+
def set_persistence_context(options_or_context)
|
51
|
+
PersistenceContext.set(self, options_or_context)
|
52
|
+
end
|
185
53
|
|
186
|
-
|
187
|
-
|
188
|
-
# @api private
|
189
|
-
#
|
190
|
-
# @example Unset the persistence options and client with options.
|
191
|
-
# Threaded.unset_options(Band)
|
192
|
-
#
|
193
|
-
# @param [ Class ] klass The model class.
|
194
|
-
#
|
195
|
-
# @return [ nil ] nil.
|
196
|
-
#
|
197
|
-
# @since 5.1.0
|
198
|
-
def unset_options(klass)
|
199
|
-
unset_persistence_options(klass)
|
200
|
-
unset_client_with_options(klass)
|
201
|
-
end
|
54
|
+
def clear_persistence_context(original_cluster = nil)
|
55
|
+
PersistenceContext.clear(self, original_cluster)
|
202
56
|
end
|
203
57
|
|
204
58
|
module ClassMethods
|
205
|
-
include Threaded
|
206
59
|
|
207
60
|
def client_name
|
208
|
-
|
209
|
-
return v.to_sym
|
210
|
-
end
|
211
|
-
super
|
61
|
+
persistence_context.client_name
|
212
62
|
end
|
213
63
|
|
214
64
|
def collection_name
|
215
|
-
|
216
|
-
return v.to_sym
|
217
|
-
end
|
218
|
-
super
|
65
|
+
persistence_context.collection_name
|
219
66
|
end
|
220
67
|
|
221
68
|
def database_name
|
222
|
-
|
223
|
-
return v.to_sym
|
224
|
-
end
|
225
|
-
super
|
69
|
+
persistence_context.database_name
|
226
70
|
end
|
227
71
|
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
#
|
237
|
-
# @example Create a document in a different client.
|
238
|
-
# Model.with(client: "secondary").create(name: "test")
|
72
|
+
def collection
|
73
|
+
persistence_context.collection
|
74
|
+
end
|
75
|
+
|
76
|
+
def mongo_client
|
77
|
+
persistence_context.client
|
78
|
+
end
|
79
|
+
|
80
|
+
# Change the persistence context for this class during the block.
|
239
81
|
#
|
240
|
-
# @example
|
241
|
-
# Model.with(
|
82
|
+
# @example Save the current document to a different collection.
|
83
|
+
# Model.with(collection: "secondary") do |m|
|
84
|
+
# m.create
|
85
|
+
# end
|
242
86
|
#
|
243
87
|
# @param [ Hash ] options The storage options.
|
244
88
|
#
|
@@ -246,56 +90,17 @@ module Mongoid
|
|
246
90
|
# @option options [ String, Symbol ] :database The database name.
|
247
91
|
# @option options [ String, Symbol ] :client The client name.
|
248
92
|
#
|
249
|
-
# @
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
set_options(self, options)
|
255
|
-
result = yield self
|
256
|
-
unset_options(self)
|
257
|
-
result
|
258
|
-
else
|
259
|
-
Proxy.new(self, (persistence_options || {}).merge(options))
|
260
|
-
end
|
261
|
-
end
|
262
|
-
end
|
263
|
-
|
264
|
-
class Proxy < BasicObject
|
265
|
-
include Threaded
|
266
|
-
|
267
|
-
undef_method :==
|
268
|
-
|
269
|
-
def initialize(target, options)
|
270
|
-
@target = target
|
271
|
-
@options = options
|
272
|
-
end
|
273
|
-
|
274
|
-
def persistence_options
|
275
|
-
@options
|
276
|
-
end
|
277
|
-
|
278
|
-
def respond_to?(*args)
|
279
|
-
@target.respond_to?(*args)
|
280
|
-
end
|
281
|
-
|
282
|
-
def method_missing(name, *args, &block)
|
283
|
-
set_persistence_options(@target, @options)
|
284
|
-
ret = @target.send(name, *args, &block)
|
285
|
-
if Mongoid::Criteria == ret.class
|
286
|
-
ret.with @options
|
287
|
-
end
|
288
|
-
ret
|
93
|
+
# @since 6.0.0
|
94
|
+
def with(options, &block)
|
95
|
+
original_cluster = persistence_context.cluster
|
96
|
+
PersistenceContext.set(self, options)
|
97
|
+
yield self
|
289
98
|
ensure
|
290
|
-
|
291
|
-
end
|
292
|
-
|
293
|
-
def send(symbol, *args)
|
294
|
-
__send__(symbol, *args)
|
99
|
+
PersistenceContext.clear(self, original_cluster)
|
295
100
|
end
|
296
101
|
|
297
|
-
def
|
298
|
-
|
102
|
+
def persistence_context
|
103
|
+
PersistenceContext.get(self) || PersistenceContext.new(self)
|
299
104
|
end
|
300
105
|
end
|
301
106
|
end
|
@@ -0,0 +1,113 @@
|
|
1
|
+
module Mongoid
|
2
|
+
module Clients
|
3
|
+
|
4
|
+
# Encapsulates behavior for getting a session from the client of a model class or instance,
|
5
|
+
# setting the session on the current thread, and yielding to a block.
|
6
|
+
# The session will be closed after the block completes or raises an error.
|
7
|
+
#
|
8
|
+
# @since 6.4.0
|
9
|
+
module Sessions
|
10
|
+
|
11
|
+
# Execute a block within the context of a session.
|
12
|
+
#
|
13
|
+
# @example Execute some operations in the context of a session.
|
14
|
+
# band.with_session(causal_consistency: true) do
|
15
|
+
# band.records << Record.create
|
16
|
+
# band.name = 'FKA Twigs'
|
17
|
+
# band.save
|
18
|
+
# band.reload
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# @param [ Hash ] options The session options. Please see the driver
|
22
|
+
# documentation for the available session options.
|
23
|
+
#
|
24
|
+
# @note You cannot do any operations in the block using models or objects
|
25
|
+
# that use a different client; the block will execute all operations
|
26
|
+
# in the context of the implicit session and operations on any models using
|
27
|
+
# another client will fail. For example, if you set a client using store_in on a
|
28
|
+
# particular model and execute an operation on it in the session context block,
|
29
|
+
# that operation can't use the block's session and an error will be raised.
|
30
|
+
# An error will also be raised if sessions are nested.
|
31
|
+
#
|
32
|
+
# @raise [ Errors::InvalidSessionUse ] If an operation is attempted on a model using another
|
33
|
+
# client from which the session was started or if sessions are nested.
|
34
|
+
#
|
35
|
+
# @return [ Object ] The result of calling the block.
|
36
|
+
#
|
37
|
+
# @yieldparam [ Mongo::Session ] The session being used for the block.
|
38
|
+
#
|
39
|
+
# @since 6.4.0
|
40
|
+
def with_session(options = {})
|
41
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_nesting) if Threaded.get_session
|
42
|
+
session = persistence_context.client.start_session(options)
|
43
|
+
Threaded.set_session(session)
|
44
|
+
yield(session)
|
45
|
+
rescue Mongo::Error::InvalidSession => ex
|
46
|
+
if ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
|
47
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:sessions_not_supported)
|
48
|
+
end
|
49
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_use)
|
50
|
+
ensure
|
51
|
+
Threaded.clear_session
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def _session
|
57
|
+
Threaded.get_session
|
58
|
+
end
|
59
|
+
|
60
|
+
module ClassMethods
|
61
|
+
|
62
|
+
# Execute a block within the context of a session.
|
63
|
+
#
|
64
|
+
# @example Execute some operations in the context of a session.
|
65
|
+
# Band.with_session(causal_consistency: true) do
|
66
|
+
# band = Band.create
|
67
|
+
# band.records << Record.new
|
68
|
+
# band.save
|
69
|
+
# band.reload.records
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# @param [ Hash ] options The session options. Please see the driver
|
73
|
+
# documentation for the available session options.
|
74
|
+
#
|
75
|
+
# @note You cannot do any operations in the block using models or objects
|
76
|
+
# that use a different client; the block will execute all operations
|
77
|
+
# in the context of the implicit session and operations on any models using
|
78
|
+
# another client will fail. For example, if you set a client using store_in on a
|
79
|
+
# particular model and execute an operation on it in the session context block,
|
80
|
+
# that operation can't use the block's session and an error will be raised.
|
81
|
+
# You also cannot nest sessions.
|
82
|
+
#
|
83
|
+
# @raise [ Errors::InvalidSessionUse ] If an operation is attempted on a model using another
|
84
|
+
# client from which the session was started or if sessions are nested.
|
85
|
+
#
|
86
|
+
# @return [ Object ] The result of calling the block.
|
87
|
+
#
|
88
|
+
# @yieldparam [ Mongo::Session ] The session being used for the block.
|
89
|
+
#
|
90
|
+
# @since 6.4.0
|
91
|
+
def with_session(options = {})
|
92
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_nesting) if Threaded.get_session
|
93
|
+
session = persistence_context.client.start_session(options)
|
94
|
+
Threaded.set_session(session)
|
95
|
+
yield(session)
|
96
|
+
rescue Mongo::Error::InvalidSession => ex
|
97
|
+
if ex.message == Mongo::Session::SESSIONS_NOT_SUPPORTED
|
98
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:sessions_not_supported)
|
99
|
+
end
|
100
|
+
raise Mongoid::Errors::InvalidSessionUse.new(:invalid_session_use)
|
101
|
+
ensure
|
102
|
+
Threaded.clear_session
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def _session
|
108
|
+
Threaded.get_session
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -61,6 +61,7 @@ module Mongoid
|
|
61
61
|
# @since 4.0.0
|
62
62
|
def reset_storage_options!
|
63
63
|
self.storage_options = storage_options_defaults.dup
|
64
|
+
PersistenceContext.clear(self)
|
64
65
|
end
|
65
66
|
|
66
67
|
# Get the default storage options.
|
@@ -74,77 +75,9 @@ module Mongoid
|
|
74
75
|
def storage_options_defaults
|
75
76
|
{
|
76
77
|
collection: name.collectionize.to_sym,
|
77
|
-
client: :default
|
78
|
-
database: -> { configured_database }
|
78
|
+
client: :default
|
79
79
|
}
|
80
80
|
end
|
81
|
-
|
82
|
-
# Get the name of the collection this model persists to.
|
83
|
-
#
|
84
|
-
# @example Get the collection name.
|
85
|
-
# Model.collection_name
|
86
|
-
#
|
87
|
-
# @return [ Symbol ] The name of the collection.
|
88
|
-
#
|
89
|
-
# @since 3.0.0
|
90
|
-
def collection_name
|
91
|
-
__evaluate__(storage_options[:collection])
|
92
|
-
end
|
93
|
-
|
94
|
-
# Get the client name for the model.
|
95
|
-
#
|
96
|
-
# @example Get the client name.
|
97
|
-
# Model.client_name
|
98
|
-
#
|
99
|
-
# @return [ Symbol ] The name of the client.
|
100
|
-
#
|
101
|
-
# @since 3.0.0
|
102
|
-
def client_name
|
103
|
-
__evaluate__(storage_options[:client])
|
104
|
-
end
|
105
|
-
|
106
|
-
# Get the database name for the model.
|
107
|
-
#
|
108
|
-
# @example Get the database name.
|
109
|
-
# Model.database_name
|
110
|
-
#
|
111
|
-
# @return [ Symbol ] The name of the client.
|
112
|
-
#
|
113
|
-
# @since 4.0.0
|
114
|
-
def database_name
|
115
|
-
__evaluate__(storage_options[:database])
|
116
|
-
end
|
117
|
-
|
118
|
-
private
|
119
|
-
|
120
|
-
# Eval the provided value, either byt calling it if it responds to call
|
121
|
-
# or returning the value itself.
|
122
|
-
#
|
123
|
-
# @api private
|
124
|
-
#
|
125
|
-
# @example Evaluate the name.
|
126
|
-
# Model.__evaluate__(:name)
|
127
|
-
#
|
128
|
-
# @param [ String, Symbol, Proc ] name The name.
|
129
|
-
#
|
130
|
-
# @return [ Symbol ] The value as a symbol.
|
131
|
-
#
|
132
|
-
# @since 3.1.0
|
133
|
-
def __evaluate__(name)
|
134
|
-
return nil unless name
|
135
|
-
name.respond_to?(:call) ? name.call.to_sym : name.to_sym
|
136
|
-
end
|
137
|
-
|
138
|
-
def configured_database
|
139
|
-
client = Mongoid.clients[client_name]
|
140
|
-
if db = client[:database]
|
141
|
-
db
|
142
|
-
elsif uri = client[:uri]
|
143
|
-
client[:database] = Mongo::URI.new(uri).database
|
144
|
-
else
|
145
|
-
nil
|
146
|
-
end
|
147
|
-
end
|
148
81
|
end
|
149
82
|
end
|
150
83
|
end
|
data/lib/mongoid/clients.rb
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
require "mongoid/clients/factory"
|
3
3
|
require "mongoid/clients/validators"
|
4
4
|
require "mongoid/clients/storage_options"
|
5
|
-
require "mongoid/clients/thread_options"
|
6
5
|
require "mongoid/clients/options"
|
6
|
+
require "mongoid/clients/sessions"
|
7
7
|
|
8
8
|
module Mongoid
|
9
9
|
module Clients
|
10
10
|
extend ActiveSupport::Concern
|
11
11
|
include StorageOptions
|
12
|
-
include ThreadOptions
|
13
12
|
include Options
|
13
|
+
include Sessions
|
14
14
|
|
15
15
|
class << self
|
16
16
|
|
@@ -35,7 +35,7 @@ module Mongoid
|
|
35
35
|
#
|
36
36
|
# @since 3.0.0
|
37
37
|
def default
|
38
|
-
|
38
|
+
with_name(:default)
|
39
39
|
end
|
40
40
|
|
41
41
|
# Disconnect all active clients.
|
@@ -63,7 +63,11 @@ module Mongoid
|
|
63
63
|
#
|
64
64
|
# @since 3.0.0
|
65
65
|
def with_name(name)
|
66
|
-
|
66
|
+
name_as_symbol = name.to_sym
|
67
|
+
return clients[name_as_symbol] if clients[name_as_symbol]
|
68
|
+
CREATE_LOCK.synchronize do
|
69
|
+
clients[name_as_symbol] ||= Clients::Factory.create(name)
|
70
|
+
end
|
67
71
|
end
|
68
72
|
|
69
73
|
def set(name, client)
|
@@ -73,67 +77,10 @@ module Mongoid
|
|
73
77
|
def clients
|
74
78
|
@clients ||= {}
|
75
79
|
end
|
76
|
-
end
|
77
|
-
|
78
|
-
# Get the collection for this model from the client. Will check for an
|
79
|
-
# overridden collection name from the store_in macro or the collection
|
80
|
-
# with a pluralized model name.
|
81
|
-
#
|
82
|
-
# @example Get the model's collection.
|
83
|
-
# Model.collection
|
84
|
-
#
|
85
|
-
# @return [ Mongo::Collection ] The collection.
|
86
|
-
#
|
87
|
-
# @since 3.0.0
|
88
|
-
def collection
|
89
|
-
mongo_client[collection_name]
|
90
|
-
end
|
91
80
|
|
92
|
-
|
93
|
-
super || self.class.mongo_client
|
94
|
-
end
|
81
|
+
private
|
95
82
|
|
96
|
-
|
97
|
-
super || self.class.collection_name
|
98
|
-
end
|
99
|
-
|
100
|
-
module ClassMethods
|
101
|
-
|
102
|
-
# Get the client for this model. This is determined in the following order:
|
103
|
-
#
|
104
|
-
# 1. Any custom configuration provided by the 'store_in' macro.
|
105
|
-
# 2. The 'default' client as provided in the mongoid.yml
|
106
|
-
#
|
107
|
-
# @example Get the client.
|
108
|
-
# Model.mongo_client
|
109
|
-
#
|
110
|
-
# @return [ Mongo::Client ] The default mongo client.
|
111
|
-
#
|
112
|
-
# @since 3.0.0
|
113
|
-
def mongo_client
|
114
|
-
return client_with_options if client_with_options
|
115
|
-
client = Clients.with_name(client_name)
|
116
|
-
opts = self.persistence_options ? self.persistence_options.dup : {}
|
117
|
-
if defined?(Mongo::Client::VALID_OPTIONS)
|
118
|
-
opts.reject! { |k, v| !Mongo::Client::VALID_OPTIONS.include?(k.to_sym) }
|
119
|
-
end
|
120
|
-
opts.merge!(database: database_name) unless client.database.name.to_sym == database_name.to_sym
|
121
|
-
client.with(opts)
|
122
|
-
end
|
123
|
-
|
124
|
-
# Get the collection for this model from the client. Will check for an
|
125
|
-
# overridden collection name from the store_in macro or the collection
|
126
|
-
# with a pluralized model name.
|
127
|
-
#
|
128
|
-
# @example Get the model's collection.
|
129
|
-
# Model.collection
|
130
|
-
#
|
131
|
-
# @return [ Mongo::Collection ] The collection.
|
132
|
-
#
|
133
|
-
# @since 3.0.0
|
134
|
-
def collection
|
135
|
-
mongo_client[collection_name]
|
136
|
-
end
|
83
|
+
CREATE_LOCK = Mutex.new
|
137
84
|
end
|
138
85
|
end
|
139
86
|
end
|