mongoid 4.0.2 → 5.0.0
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
- data/CHANGELOG.md +66 -1
- data/README.md +11 -19
- data/lib/config/locales/en.yml +33 -30
- data/lib/mongoid/atomic.rb +2 -4
- data/lib/mongoid/attributes/processing.rb +4 -1
- data/lib/mongoid/attributes/readonly.rb +2 -2
- data/lib/mongoid/attributes.rb +7 -7
- data/lib/mongoid/changeable.rb +4 -6
- data/lib/mongoid/clients/factory.rb +78 -0
- data/lib/mongoid/{sessions → clients}/options.rb +30 -19
- data/lib/mongoid/{sessions → clients}/storage_options.rb +27 -13
- data/lib/mongoid/{sessions → clients}/thread_options.rb +6 -3
- data/lib/mongoid/{sessions → clients}/validators/storage.rb +5 -2
- data/lib/mongoid/clients/validators.rb +2 -0
- data/lib/mongoid/clients.rb +141 -0
- data/lib/mongoid/composable.rb +3 -3
- data/lib/mongoid/config/environment.rb +1 -1
- data/lib/mongoid/config/options.rb +1 -1
- data/lib/mongoid/config/validators/{session.rb → client.rb} +31 -28
- data/lib/mongoid/config/validators/option.rb +1 -1
- data/lib/mongoid/config/validators.rb +1 -1
- data/lib/mongoid/config.rb +39 -41
- data/lib/mongoid/contextual/aggregable/mongo.rb +1 -1
- data/lib/mongoid/contextual/atomic.rb +11 -11
- data/lib/mongoid/contextual/command.rb +9 -6
- data/lib/mongoid/contextual/geo_near.rb +17 -1
- data/lib/mongoid/contextual/map_reduce.rb +12 -11
- data/lib/mongoid/contextual/memory.rb +2 -5
- data/lib/mongoid/contextual/mongo.rb +92 -82
- data/lib/mongoid/contextual/none.rb +13 -0
- data/lib/mongoid/copyable.rb +6 -1
- data/lib/mongoid/criteria.rb +37 -4
- data/lib/mongoid/document.rb +3 -4
- data/lib/mongoid/errors/{mixed_session_configuration.rb → mixed_client_configuration.rb} +5 -5
- data/lib/mongoid/errors/mongoid_error.rb +15 -9
- data/lib/mongoid/errors/no_client_config.rb +22 -0
- data/lib/mongoid/errors/{no_session_database.rb → no_client_database.rb} +4 -4
- data/lib/mongoid/errors/{no_session_hosts.rb → no_client_hosts.rb} +4 -4
- data/lib/mongoid/errors/{no_sessions_config.rb → no_clients_config.rb} +4 -4
- data/lib/mongoid/errors/no_default_client.rb +23 -0
- data/lib/mongoid/errors.rb +6 -6
- data/lib/mongoid/extensions/hash.rb +5 -1
- data/lib/mongoid/extensions/object.rb +3 -2
- data/lib/mongoid/extensions/set.rb +5 -5
- data/lib/mongoid/factory.rb +4 -2
- data/lib/mongoid/fields.rb +7 -2
- data/lib/mongoid/findable.rb +4 -1
- data/lib/mongoid/indexable.rb +15 -9
- data/lib/mongoid/persistable/creatable.rb +2 -2
- data/lib/mongoid/persistable/deletable.rb +3 -3
- data/lib/mongoid/persistable/incrementable.rb +1 -1
- data/lib/mongoid/persistable/logical.rb +1 -1
- data/lib/mongoid/persistable/poppable.rb +1 -1
- data/lib/mongoid/persistable/pullable.rb +2 -2
- data/lib/mongoid/persistable/pushable.rb +2 -2
- data/lib/mongoid/persistable/renamable.rb +1 -1
- data/lib/mongoid/persistable/settable.rb +1 -1
- data/lib/mongoid/persistable/unsettable.rb +1 -1
- data/lib/mongoid/persistable/updatable.rb +2 -2
- data/lib/mongoid/persistable/upsertable.rb +1 -1
- data/lib/mongoid/persistable.rb +1 -2
- data/lib/mongoid/query_cache.rb +98 -104
- data/lib/mongoid/railtie.rb +4 -25
- data/lib/mongoid/railties/database.rake +1 -1
- data/lib/mongoid/relations/bindings/referenced/many_to_many.rb +3 -2
- data/lib/mongoid/relations/builders.rb +3 -1
- data/lib/mongoid/relations/counter_cache.rb +1 -1
- data/lib/mongoid/relations/embedded/batchable.rb +3 -10
- data/lib/mongoid/relations/embedded/many.rb +4 -2
- data/lib/mongoid/relations/embedded/one.rb +1 -0
- data/lib/mongoid/relations/many.rb +1 -0
- data/lib/mongoid/relations/metadata.rb +14 -0
- data/lib/mongoid/relations/proxy.rb +6 -6
- data/lib/mongoid/relations/referenced/many.rb +2 -1
- data/lib/mongoid/relations/targets/enumerable.rb +11 -11
- data/lib/mongoid/relations/touchable.rb +1 -1
- data/lib/mongoid/reloadable.rb +2 -2
- data/lib/mongoid/scopable.rb +6 -17
- data/lib/mongoid/selectable.rb +1 -36
- data/lib/mongoid/serializable.rb +2 -2
- data/lib/mongoid/stateful.rb +0 -1
- data/lib/mongoid/tasks/database.rake +2 -2
- data/lib/mongoid/tasks/database.rb +24 -17
- data/lib/mongoid/threaded/lifecycle.rb +21 -16
- data/lib/mongoid/threaded.rb +54 -33
- data/lib/mongoid/traversable.rb +17 -1
- data/lib/mongoid/validatable/queryable.rb +1 -1
- data/lib/mongoid/validatable/uniqueness.rb +3 -20
- data/lib/mongoid/validatable.rb +1 -1
- data/lib/mongoid/version.rb +1 -1
- data/lib/mongoid.rb +28 -21
- data/lib/rails/generators/mongoid/config/templates/mongoid.yml +91 -57
- data/lib/rails/mongoid.rb +2 -2
- data/spec/app/models/audio.rb +1 -1
- data/spec/app/models/band.rb +1 -0
- data/spec/app/models/code.rb +6 -0
- data/spec/app/models/company.rb +5 -0
- data/spec/app/models/label.rb +7 -0
- data/spec/app/models/pub.rb +6 -0
- data/spec/app/models/staff.rb +7 -0
- data/spec/app/models/store_as_dup_test1.rb +5 -0
- data/spec/app/models/store_as_dup_test2.rb +5 -0
- data/spec/config/mongoid.yml +7 -25
- data/spec/mongoid/atomic/paths_spec.rb +3 -11
- data/spec/mongoid/attributes/nested_spec.rb +16 -16
- data/spec/mongoid/attributes/readonly_spec.rb +80 -18
- data/spec/mongoid/attributes_spec.rb +3 -3
- data/spec/mongoid/changeable_spec.rb +156 -0
- data/spec/mongoid/clients/factory_spec.rb +284 -0
- data/spec/mongoid/{sessions → clients}/options_spec.rb +4 -6
- data/spec/mongoid/clients_spec.rb +754 -0
- data/spec/mongoid/config/environment_spec.rb +14 -11
- data/spec/mongoid/config_spec.rb +33 -48
- data/spec/mongoid/contextual/atomic_spec.rb +1 -17
- data/spec/mongoid/contextual/geo_near_spec.rb +35 -0
- data/spec/mongoid/contextual/mongo_spec.rb +26 -83
- data/spec/mongoid/contextual/none_spec.rb +15 -0
- data/spec/mongoid/copyable_spec.rb +35 -1
- data/spec/mongoid/criteria/findable_spec.rb +197 -0
- data/spec/mongoid/criteria/modifiable_spec.rb +7 -29
- data/spec/mongoid/criteria_spec.rb +74 -91
- data/spec/mongoid/document_spec.rb +1 -1
- data/spec/mongoid/errors/{mixed_session_configuration_spec.rb → mixed_client_configuration_spec.rb} +1 -1
- data/spec/mongoid/errors/mongoid_error_spec.rb +19 -3
- data/spec/mongoid/errors/{no_session_config_spec.rb → no_client_config_spec.rb} +4 -4
- data/spec/mongoid/errors/{no_session_database_spec.rb → no_client_database_spec.rb} +4 -4
- data/spec/mongoid/errors/{no_session_hosts_spec.rb → no_client_hosts_spec.rb} +3 -3
- data/spec/mongoid/errors/{no_sessions_config_spec.rb → no_clients_config_spec.rb} +2 -2
- data/spec/mongoid/fields/localized_spec.rb +1 -0
- data/spec/mongoid/fields_spec.rb +1 -0
- data/spec/mongoid/findable_spec.rb +2 -23
- data/spec/mongoid/indexable_spec.rb +12 -8
- data/spec/mongoid/interceptable_spec.rb +15 -0
- data/spec/mongoid/persistable/settable_spec.rb +16 -0
- data/spec/mongoid/persistable/updatable_spec.rb +3 -2
- data/spec/mongoid/persistable_spec.rb +4 -4
- data/spec/mongoid/query_cache_spec.rb +13 -8
- data/spec/mongoid/relations/auto_save_spec.rb +1 -1
- data/spec/mongoid/relations/counter_cache_spec.rb +34 -0
- data/spec/mongoid/relations/eager/belongs_to_spec.rb +9 -0
- data/spec/mongoid/relations/eager/has_and_belongs_to_many_spec.rb +3 -3
- data/spec/mongoid/relations/embedded/many_spec.rb +123 -1
- data/spec/mongoid/relations/embedded/one_spec.rb +3 -3
- data/spec/mongoid/relations/proxy_spec.rb +28 -0
- data/spec/mongoid/relations/referenced/in_spec.rb +1 -1
- data/spec/mongoid/relations/referenced/many_spec.rb +47 -23
- data/spec/mongoid/relations/referenced/many_to_many_spec.rb +1 -1
- data/spec/mongoid/relations/referenced/one_spec.rb +1 -1
- data/spec/mongoid/relations/targets/enumerable_spec.rb +9 -2
- data/spec/mongoid/reloadable_spec.rb +6 -6
- data/spec/mongoid/scopable_spec.rb +41 -28
- data/spec/mongoid/selectable_spec.rb +6 -16
- data/spec/mongoid/tasks/database_rake_spec.rb +13 -13
- data/spec/mongoid/tasks/database_spec.rb +2 -2
- data/spec/mongoid/threaded_spec.rb +0 -7
- data/spec/mongoid/traversable_spec.rb +2 -2
- data/spec/mongoid/validatable/uniqueness_spec.rb +30 -1
- data/spec/mongoid_spec.rb +13 -15
- data/spec/rails/mongoid_spec.rb +13 -4
- data/spec/spec_helper.rb +44 -27
- data/spec/support/authorization.rb +12 -0
- data/spec/support/expectations.rb +14 -0
- metadata +50 -57
- data/lib/mongoid/contextual/find_and_modify.rb +0 -69
- data/lib/mongoid/contextual/text_search.rb +0 -178
- data/lib/mongoid/criteria/#findable.rb# +0 -141
- data/lib/mongoid/errors/no_default_session.rb +0 -23
- data/lib/mongoid/errors/no_session_config.rb +0 -22
- data/lib/mongoid/log_subscriber.rb +0 -55
- data/lib/mongoid/positional.rb +0 -71
- data/lib/mongoid/sessions/factory.rb +0 -131
- data/lib/mongoid/sessions/mongo_uri.rb +0 -93
- data/lib/mongoid/sessions/validators.rb +0 -2
- data/lib/mongoid/sessions.rb +0 -125
- data/lib/mongoid/support/query_counter.rb +0 -23
- data/spec/helpers.rb +0 -18
- data/spec/mongoid/#atomic_spec.rb# +0 -365
- data/spec/mongoid/contextual/find_and_modify_spec.rb +0 -220
- data/spec/mongoid/contextual/text_search_spec.rb +0 -209
- data/spec/mongoid/log_subscriber_spec.rb +0 -75
- data/spec/mongoid/positional_spec.rb +0 -222
- data/spec/mongoid/sessions/factory_spec.rb +0 -333
- data/spec/mongoid/sessions/mongo_uri_spec.rb +0 -103
- data/spec/mongoid/sessions_spec.rb +0 -1252
data/lib/mongoid/sessions.rb
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
require "mongoid/sessions/factory"
|
|
3
|
-
require "mongoid/sessions/validators"
|
|
4
|
-
require "mongoid/sessions/storage_options"
|
|
5
|
-
require "mongoid/sessions/thread_options"
|
|
6
|
-
require "mongoid/sessions/options"
|
|
7
|
-
|
|
8
|
-
module Mongoid
|
|
9
|
-
module Sessions
|
|
10
|
-
extend ActiveSupport::Concern
|
|
11
|
-
include StorageOptions
|
|
12
|
-
include ThreadOptions
|
|
13
|
-
include Options
|
|
14
|
-
|
|
15
|
-
class << self
|
|
16
|
-
# Clear all sessions from the current thread.
|
|
17
|
-
#
|
|
18
|
-
# @example Clear all sessions.
|
|
19
|
-
# Mongoid::Sessions.clear
|
|
20
|
-
#
|
|
21
|
-
# @return [ Array ] The empty sessions.
|
|
22
|
-
#
|
|
23
|
-
# @since 3.0.0
|
|
24
|
-
def clear
|
|
25
|
-
Threaded.sessions.clear
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Get the default session.
|
|
29
|
-
#
|
|
30
|
-
# @example Get the default session.
|
|
31
|
-
# Mongoid::Sessions.default
|
|
32
|
-
#
|
|
33
|
-
# @return [ Moped::Session ] The default session.
|
|
34
|
-
#
|
|
35
|
-
# @since 3.0.0
|
|
36
|
-
def default
|
|
37
|
-
Threaded.sessions[:default] ||= Sessions::Factory.default
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
# Disconnect all active sessions.
|
|
41
|
-
#
|
|
42
|
-
# @example Disconnect all active sessions.
|
|
43
|
-
# Mongoid::Sessions.disconnect
|
|
44
|
-
#
|
|
45
|
-
# @return [ true ] True.
|
|
46
|
-
#
|
|
47
|
-
# @since 3.1.0
|
|
48
|
-
def disconnect
|
|
49
|
-
Threaded.sessions.values.each do |session|
|
|
50
|
-
session.disconnect
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Get a session with the provided name.
|
|
55
|
-
#
|
|
56
|
-
# @example Get a session with the name.
|
|
57
|
-
# Mongoid::Sessions.with_name(:replica)
|
|
58
|
-
#
|
|
59
|
-
# @param [ Symbol ] name The name of the session.
|
|
60
|
-
#
|
|
61
|
-
# @return [ Moped::Session ] The named session.
|
|
62
|
-
#
|
|
63
|
-
# @since 3.0.0
|
|
64
|
-
def with_name(name)
|
|
65
|
-
Threaded.sessions[name.to_sym] ||= Sessions::Factory.create(name)
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Get the collection for this model from the session. Will check for an
|
|
70
|
-
# overridden collection name from the store_in macro or the collection
|
|
71
|
-
# with a pluralized model name.
|
|
72
|
-
#
|
|
73
|
-
# @example Get the model's collection.
|
|
74
|
-
# Model.collection
|
|
75
|
-
#
|
|
76
|
-
# @return [ Moped::Collection ] The collection.
|
|
77
|
-
#
|
|
78
|
-
# @since 3.0.0
|
|
79
|
-
def collection
|
|
80
|
-
mongo_session[collection_name]
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def mongo_session
|
|
84
|
-
super || self.class.mongo_session
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def collection_name
|
|
88
|
-
super || self.class.collection_name
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
module ClassMethods
|
|
92
|
-
|
|
93
|
-
# Get the session for this model. This is determined in the following order:
|
|
94
|
-
#
|
|
95
|
-
# 1. Any custom configuration provided by the 'store_in' macro.
|
|
96
|
-
# 2. The 'default' session as provided in the mongoid.yml
|
|
97
|
-
#
|
|
98
|
-
# @example Get the session.
|
|
99
|
-
# Model.mongo_session
|
|
100
|
-
#
|
|
101
|
-
# @return [ Moped::Session ] The default moped session.
|
|
102
|
-
#
|
|
103
|
-
# @since 3.0.0
|
|
104
|
-
def mongo_session
|
|
105
|
-
session = Sessions.with_name(session_name)
|
|
106
|
-
session.use(database_name)
|
|
107
|
-
self.persistence_options ? session.with(self.persistence_options) : session
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# Get the collection for this model from the session. Will check for an
|
|
111
|
-
# overridden collection name from the store_in macro or the collection
|
|
112
|
-
# with a pluralized model name.
|
|
113
|
-
#
|
|
114
|
-
# @example Get the model's collection.
|
|
115
|
-
# Model.collection
|
|
116
|
-
#
|
|
117
|
-
# @return [ Moped::Collection ] The collection.
|
|
118
|
-
#
|
|
119
|
-
# @since 3.0.0
|
|
120
|
-
def collection
|
|
121
|
-
mongo_session[collection_name]
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
end
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
module Mongoid
|
|
2
|
-
|
|
3
|
-
class QueryCounter
|
|
4
|
-
attr_reader :events
|
|
5
|
-
|
|
6
|
-
def initialize
|
|
7
|
-
@events = []
|
|
8
|
-
end
|
|
9
|
-
|
|
10
|
-
def instrument
|
|
11
|
-
subscriber = ActiveSupport::Notifications.subscribe('query.moped') do |*args|
|
|
12
|
-
@events << ActiveSupport::Notifications::Event.new(*args)
|
|
13
|
-
end
|
|
14
|
-
yield
|
|
15
|
-
ensure
|
|
16
|
-
ActiveSupport::Notifications.unsubscribe(subscriber)
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
def inspect
|
|
20
|
-
@events.map { |e| e.payload[:ops].map(&:log_inspect) }.join("\n")
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
data/spec/helpers.rb
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
require 'mongoid/support/query_counter'
|
|
2
|
-
|
|
3
|
-
module Mongoid
|
|
4
|
-
module SpecHelpers
|
|
5
|
-
def expect_query(number, &block)
|
|
6
|
-
query_counter = Mongoid::QueryCounter.new
|
|
7
|
-
query_counter.instrument(&block)
|
|
8
|
-
expect(query_counter.events.size).to(eq(number), %[
|
|
9
|
-
Expected to receive #{number} queries, it received #{query_counter.events.size}
|
|
10
|
-
#{query_counter.inspect}
|
|
11
|
-
])
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def expect_no_queries(&block)
|
|
15
|
-
expect_query(0, &block)
|
|
16
|
-
end
|
|
17
|
-
end
|
|
18
|
-
end
|
|
@@ -1,365 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe Mongoid::Atomic do
|
|
4
|
-
|
|
5
|
-
describe "#add_atomic_pull" do
|
|
6
|
-
|
|
7
|
-
let!(:person) do
|
|
8
|
-
Person.create
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
let(:address) do
|
|
12
|
-
person.addresses.create
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
let(:location) do
|
|
16
|
-
address.locations.create
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
before do
|
|
20
|
-
person.add_atomic_pull(address)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
it "adds the document to the delayed atomic pulls" do
|
|
24
|
-
expect(person.delayed_atomic_pulls["addresses"]).to eq([ address ])
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
it "flags the document for destruction" do
|
|
28
|
-
expect(address).to be_flagged_for_destroy
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
describe "#add_atomic_unset" do
|
|
33
|
-
|
|
34
|
-
let!(:person) do
|
|
35
|
-
Person.new
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
let(:name) do
|
|
39
|
-
person.build_name
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
before do
|
|
43
|
-
person.add_atomic_unset(name)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it "adds the document to the delayed atomic unsets" do
|
|
47
|
-
expect(person.delayed_atomic_unsets["name"]).to eq([ name ])
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
it "flags the document for destruction" do
|
|
51
|
-
expect(name).to be_flagged_for_destroy
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
describe "#atomic_updates" do
|
|
56
|
-
|
|
57
|
-
context "when the document is persisted" do
|
|
58
|
-
|
|
59
|
-
let(:person) do
|
|
60
|
-
Person.create
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
context "when the document is modified" do
|
|
64
|
-
|
|
65
|
-
before do
|
|
66
|
-
person.title = "Sir"
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
it "returns the atomic updates" do
|
|
70
|
-
expect(person.atomic_updates).to eq({ "$set" => { "title" => "Sir" }})
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
context "when an embeds many child is added" do
|
|
74
|
-
|
|
75
|
-
let!(:address) do
|
|
76
|
-
person.addresses.build(street: "Oxford St")
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
it "returns a $set and $pushAll for modifications" do
|
|
80
|
-
expect(person.atomic_updates).to eq(
|
|
81
|
-
{
|
|
82
|
-
"$set" => { "title" => "Sir" },
|
|
83
|
-
"$pushAll" => { "addresses" => [
|
|
84
|
-
{ "_id" => "oxford-st", "street" => "Oxford St" }
|
|
85
|
-
]}
|
|
86
|
-
}
|
|
87
|
-
)
|
|
88
|
-
end
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
context "when an embeds one child is added" do
|
|
92
|
-
|
|
93
|
-
let!(:name) do
|
|
94
|
-
person.build_name(first_name: "Lionel")
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
it "returns a $set for modifications" do
|
|
98
|
-
expect(person.atomic_updates).to eq(
|
|
99
|
-
{
|
|
100
|
-
"$set" => {
|
|
101
|
-
"title" => "Sir",
|
|
102
|
-
"name" => { "_id" => "Lionel-", "first_name" => "Lionel" }
|
|
103
|
-
}
|
|
104
|
-
}
|
|
105
|
-
)
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
context "when an existing embeds many gets modified" do
|
|
110
|
-
|
|
111
|
-
let!(:address) do
|
|
112
|
-
person.addresses.create(street: "Oxford St")
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
before do
|
|
116
|
-
address.street = "Bond St"
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
context "when asking for the updates from the root" do
|
|
120
|
-
|
|
121
|
-
it "returns the $set with correct position and modifications" do
|
|
122
|
-
expect(person.atomic_updates).to eq(
|
|
123
|
-
{ "$set" => { "title" => "Sir", "addresses.0.street" => "Bond St" }}
|
|
124
|
-
)
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
context "when asking for the updates from the child" do
|
|
129
|
-
|
|
130
|
-
it "returns the $set with correct position and modifications" do
|
|
131
|
-
expect(address.atomic_updates).to eq(
|
|
132
|
-
{ "$set" => { "addresses.0.street" => "Bond St" }}
|
|
133
|
-
)
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
context "when an existing 2nd level embedded child gets modified" do
|
|
138
|
-
|
|
139
|
-
let!(:location) do
|
|
140
|
-
address.locations.create(name: "Home")
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
before do
|
|
144
|
-
location.name = "Work"
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
context "when asking for the updates from the root" do
|
|
148
|
-
|
|
149
|
-
it "returns the $set with correct positions and modifications" do
|
|
150
|
-
expect(person.atomic_updates).to eq(
|
|
151
|
-
{ "$set" => {
|
|
152
|
-
"title" => "Sir",
|
|
153
|
-
"addresses.0.street" => "Bond St",
|
|
154
|
-
"addresses.0.locations.0.name" => "Work" }
|
|
155
|
-
}
|
|
156
|
-
)
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
context "when asking for the updates from the 1st level child" do
|
|
161
|
-
|
|
162
|
-
it "returns the $set with correct positions and modifications" do
|
|
163
|
-
expect(address.atomic_updates).to eq(
|
|
164
|
-
{ "$set" => {
|
|
165
|
-
"addresses.0.street" => "Bond St",
|
|
166
|
-
"addresses.0.locations.0.name" => "Work" }
|
|
167
|
-
}
|
|
168
|
-
)
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
context "when asking for the updates from the 2nd level child" do
|
|
173
|
-
|
|
174
|
-
it "returns the $set with correct positions and modifications" do
|
|
175
|
-
expect(location.atomic_updates).to eq(
|
|
176
|
-
{ "$set" => {
|
|
177
|
-
"addresses.0.locations.0.name" => "Work" }
|
|
178
|
-
}
|
|
179
|
-
)
|
|
180
|
-
end
|
|
181
|
-
end
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
context "when a 2nd level embedded child gets added" do
|
|
185
|
-
|
|
186
|
-
let!(:location) do
|
|
187
|
-
address.locations.build(name: "Home")
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
context "when asking for the updates from the root" do
|
|
191
|
-
|
|
192
|
-
it "returns the $set with correct positions and modifications" do
|
|
193
|
-
expect(person.atomic_updates).to eq(
|
|
194
|
-
{
|
|
195
|
-
"$set" => {
|
|
196
|
-
"title" => "Sir",
|
|
197
|
-
"addresses.0.street" => "Bond St"
|
|
198
|
-
},
|
|
199
|
-
conflicts: {
|
|
200
|
-
"$pushAll" => {
|
|
201
|
-
"addresses.0.locations" => [{ "_id" => location.id, "name" => "Home" }]
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
)
|
|
206
|
-
end
|
|
207
|
-
end
|
|
208
|
-
|
|
209
|
-
context "when asking for the updates from the 1st level child" do
|
|
210
|
-
|
|
211
|
-
it "returns the $set with correct positions and modifications" do
|
|
212
|
-
expect(address.atomic_updates).to eq(
|
|
213
|
-
{
|
|
214
|
-
"$set" => {
|
|
215
|
-
"addresses.0.street" => "Bond St"
|
|
216
|
-
},
|
|
217
|
-
conflicts: {
|
|
218
|
-
"$pushAll" => {
|
|
219
|
-
"addresses.0.locations" => [{ "_id" => location.id, "name" => "Home" }]
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
)
|
|
224
|
-
end
|
|
225
|
-
end
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
context "when an embedded child gets unset" do
|
|
229
|
-
|
|
230
|
-
before do
|
|
231
|
-
person.attributes = { addresses: nil }
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
let(:updates) do
|
|
235
|
-
person.atomic_updates
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
it "returns the $set for the first level and $unset for other." do
|
|
239
|
-
expect(updates).to eq({
|
|
240
|
-
"$unset" => { "addresses" => true },
|
|
241
|
-
"$set" => { "title" => "Sir" }
|
|
242
|
-
})
|
|
243
|
-
end
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
context "when adding a new second level child" do
|
|
247
|
-
|
|
248
|
-
let!(:new_address) do
|
|
249
|
-
person.addresses.build(street: "Another")
|
|
250
|
-
end
|
|
251
|
-
|
|
252
|
-
let!(:location) do
|
|
253
|
-
new_address.locations.build(name: "Home")
|
|
254
|
-
end
|
|
255
|
-
|
|
256
|
-
context "when asking for the updates from the root document" do
|
|
257
|
-
|
|
258
|
-
it "returns the $set for 1st level and other for the 2nd level" do
|
|
259
|
-
expect(person.atomic_updates).to eq(
|
|
260
|
-
{
|
|
261
|
-
"$set" => {
|
|
262
|
-
"title" => "Sir",
|
|
263
|
-
"addresses.0.street" => "Bond St"
|
|
264
|
-
},
|
|
265
|
-
conflicts: {
|
|
266
|
-
"$pushAll" => {
|
|
267
|
-
"addresses" => [{
|
|
268
|
-
"_id" => new_address.id,
|
|
269
|
-
"street" => "Another",
|
|
270
|
-
"locations" => [
|
|
271
|
-
"_id" => location.id,
|
|
272
|
-
"name" => "Home"
|
|
273
|
-
]
|
|
274
|
-
}]
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
}
|
|
278
|
-
)
|
|
279
|
-
end
|
|
280
|
-
end
|
|
281
|
-
|
|
282
|
-
context "when asking for the updates from the 1st level document" do
|
|
283
|
-
|
|
284
|
-
it "returns the $set for 1st level and other for the 2nd level" do
|
|
285
|
-
expect(address.atomic_updates).to eq(
|
|
286
|
-
{ "$set" => { "addresses.0.street" => "Bond St" }}
|
|
287
|
-
)
|
|
288
|
-
end
|
|
289
|
-
end
|
|
290
|
-
end
|
|
291
|
-
|
|
292
|
-
context "when adding a new child beetween two existing and updating one of them" do
|
|
293
|
-
|
|
294
|
-
let!(:new_address) do
|
|
295
|
-
person.addresses.build(street: "Ipanema")
|
|
296
|
-
end
|
|
297
|
-
|
|
298
|
-
let!(:location) do
|
|
299
|
-
new_address.locations.build(name: "Home")
|
|
300
|
-
end
|
|
301
|
-
|
|
302
|
-
before do
|
|
303
|
-
person.addresses[0] = new_address
|
|
304
|
-
person.addresses[1] = address
|
|
305
|
-
end
|
|
306
|
-
|
|
307
|
-
it "returns the $set for 1st and 2nd level and other for the 3nd level" do
|
|
308
|
-
expect(person.atomic_updates).to eq(
|
|
309
|
-
{
|
|
310
|
-
"$set" => {
|
|
311
|
-
"title" => "Sir"
|
|
312
|
-
},
|
|
313
|
-
"$pushAll" => {
|
|
314
|
-
"addresses" => [{
|
|
315
|
-
"_id" => new_address.id,
|
|
316
|
-
"street" => "Ipanema",
|
|
317
|
-
"locations" => [
|
|
318
|
-
"_id" => location.id,
|
|
319
|
-
"name" => "Home"
|
|
320
|
-
]
|
|
321
|
-
}]
|
|
322
|
-
},
|
|
323
|
-
conflicts: {
|
|
324
|
-
"$set" => { "addresses.0.street"=>"Bond St" }
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
)
|
|
328
|
-
end
|
|
329
|
-
end
|
|
330
|
-
end
|
|
331
|
-
|
|
332
|
-
context "when adding new embedded docs at multiple levels" do
|
|
333
|
-
|
|
334
|
-
let!(:address) do
|
|
335
|
-
person.addresses.build(street: "Another")
|
|
336
|
-
end
|
|
337
|
-
|
|
338
|
-
let!(:location) do
|
|
339
|
-
address.locations.build(name: "Home")
|
|
340
|
-
end
|
|
341
|
-
|
|
342
|
-
it "returns the proper $sets and $pushAlls for all levels" do
|
|
343
|
-
expect(person.atomic_updates).to eq(
|
|
344
|
-
{
|
|
345
|
-
"$set" => {
|
|
346
|
-
"title" => "Sir",
|
|
347
|
-
},
|
|
348
|
-
"$pushAll" => {
|
|
349
|
-
"addresses" => [{
|
|
350
|
-
"_id" => address.id,
|
|
351
|
-
"street" => "Another",
|
|
352
|
-
"locations" => [
|
|
353
|
-
"_id" => location.id,
|
|
354
|
-
"name" => "Home"
|
|
355
|
-
]
|
|
356
|
-
}]
|
|
357
|
-
}
|
|
358
|
-
}
|
|
359
|
-
)
|
|
360
|
-
end
|
|
361
|
-
end
|
|
362
|
-
end
|
|
363
|
-
end
|
|
364
|
-
end
|
|
365
|
-
end
|