Module: Mongoid::Atomic
- Extended by:
- ActiveSupport::Concern
- Included in:
- Components, Contextual::Mongo, Persistence
- Defined in:
- lib/mongoid/atomic.rb,
lib/mongoid/atomic/modifiers.rb,
lib/mongoid/atomic/paths/root.rb,
lib/mongoid/atomic/positionable.rb,
lib/mongoid/atomic/paths/embedded.rb,
lib/mongoid/atomic/paths/embedded/one.rb,
lib/mongoid/atomic/paths/embedded/many.rb
Overview
This module contains the logic for supporting atomic operations against the database.
Defined Under Namespace
Modules: Paths, Positionable Classes: Modifiers
Constant Summary collapse
- UPDATES =
[ :atomic_array_pushes, :atomic_array_pulls, :atomic_array_add_to_sets, :atomic_pulls, :delayed_atomic_sets, :delayed_atomic_pulls, :delayed_atomic_unsets ]
Instance Method Summary collapse
-
#add_atomic_pull(document) ⇒ Object
Add the document as an atomic pull.
-
#add_atomic_unset(document) ⇒ Array<Document>
Add an atomic unset for the document.
-
#atomic_array_add_to_sets ⇒ Hash
For array fields these are the unique adds that need to happen.
-
#atomic_array_pulls ⇒ Hash
For array fields these are the pulls that need to happen.
-
#atomic_array_pushes ⇒ Hash
For array fields these are the pushes that need to happen.
-
#atomic_attribute_name(name) ⇒ String
Returns path of the attribute for modification.
-
#atomic_delete_modifier ⇒ String
Get the removal modifier for the document.
-
#atomic_insert_modifier ⇒ String
Get the insertion modifier for the document.
-
#atomic_path ⇒ String
Return the path to this
Document
in JSON notation, used for atomic updates via $set in MongoDB. -
#atomic_paths ⇒ Object
Get the atomic paths utility for this document.
-
#atomic_position ⇒ String
Returns the positional operator of this document for modification.
-
#atomic_pulls ⇒ Array<Hash>
Get all the attributes that need to be pulled.
-
#atomic_pushes ⇒ Hash
Get all the push attributes that need to occur.
-
#atomic_selector ⇒ String
Return the selector for this document to be matched exactly for use with MongoDB’s $ operator.
-
#atomic_sets ⇒ Hash
Get all the attributes that need to be set.
-
#atomic_unsets ⇒ Array<Hash>
Get all the attributes that need to be unset.
-
#atomic_updates(use_indexes = false) ⇒ Hash
(also: #_updates)
Get all the atomic updates that need to happen for the current
Document
. -
#delayed_atomic_pulls ⇒ Hash
Get a hash of atomic pulls that are pending.
-
#delayed_atomic_sets ⇒ Hash
Get all the atomic sets that have had their saves delayed.
-
#delayed_atomic_unsets ⇒ Hash
Get the delayed atomic unsets.
-
#flag_as_destroyed ⇒ String
Flag the document as destroyed and return the atomic path.
-
#flagged_destroys ⇒ Array<Proc>
Get the flagged destroys.
-
#process_flagged_destroys ⇒ Array
Process all the pending flagged destroys from nested attributes.
Instance Method Details
#add_atomic_pull(document) ⇒ Object
Add the document as an atomic pull.
37 38 39 40 |
# File 'lib/mongoid/atomic.rb', line 37 def add_atomic_pull(document) document.flagged_for_destroy = true (delayed_atomic_pulls[document..to_s] ||= []).push(document) end |
#add_atomic_unset(document) ⇒ Array<Document>
Add an atomic unset for the document.
52 53 54 55 |
# File 'lib/mongoid/atomic.rb', line 52 def add_atomic_unset(document) document.flagged_for_destroy = true (delayed_atomic_unsets[document..to_s] ||= []).push(document) end |
#atomic_array_add_to_sets ⇒ Hash
For array fields these are the unique adds that need to happen.
101 102 103 |
# File 'lib/mongoid/atomic.rb', line 101 def atomic_array_add_to_sets @atomic_array_add_to_sets ||= {} end |
#atomic_array_pulls ⇒ Hash
For array fields these are the pulls that need to happen.
89 90 91 |
# File 'lib/mongoid/atomic.rb', line 89 def atomic_array_pulls @atomic_array_pulls ||= {} end |
#atomic_array_pushes ⇒ Hash
For array fields these are the pushes that need to happen.
77 78 79 |
# File 'lib/mongoid/atomic.rb', line 77 def atomic_array_pushes @atomic_array_pushes ||= {} end |
#atomic_attribute_name(name) ⇒ String
Returns path of the attribute for modification
65 66 67 |
# File 'lib/mongoid/atomic.rb', line 65 def atomic_attribute_name(name) ? "#{atomic_position}.#{name}" : name end |
#atomic_delete_modifier ⇒ String
Get the removal modifier for the document. Will be nil on root documents, $unset on embeds_one, $set on embeds_many.
147 148 149 |
# File 'lib/mongoid/atomic.rb', line 147 def atomic_delete_modifier atomic_paths.delete_modifier end |
#atomic_insert_modifier ⇒ String
Get the insertion modifier for the document. Will be nil on root documents, $set on embeds_one, $push on embeds_many.
158 159 160 |
# File 'lib/mongoid/atomic.rb', line 158 def atomic_insert_modifier atomic_paths.insert_modifier end |
#atomic_path ⇒ String
Return the path to this Document
in JSON notation, used for atomic updates via $set in MongoDB.
169 170 171 |
# File 'lib/mongoid/atomic.rb', line 169 def atomic_path atomic_paths.path end |
#atomic_paths ⇒ Object
Get the atomic paths utility for this document.
191 192 193 |
# File 'lib/mongoid/atomic.rb', line 191 def atomic_paths @atomic_paths ||= ? .path(self) : Atomic::Paths::Root.new(self) end |
#atomic_position ⇒ String
Returns the positional operator of this document for modification.
179 180 181 |
# File 'lib/mongoid/atomic.rb', line 179 def atomic_position atomic_paths.position end |
#atomic_pulls ⇒ Array<Hash>
Get all the attributes that need to be pulled.
203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/mongoid/atomic.rb', line 203 def atomic_pulls pulls = {} delayed_atomic_pulls.each_pair do |_, docs| path = nil ids = docs.map do |doc| path ||= doc.flag_as_destroyed doc.id end pulls[path] = { "_id" => { "$in" => ids }} and path = nil end pulls end |
#atomic_pushes ⇒ Hash
Get all the push attributes that need to occur.
224 225 226 |
# File 'lib/mongoid/atomic.rb', line 224 def atomic_pushes pushable? ? { atomic_position => as_document } : {} end |
#atomic_selector ⇒ String
Return the selector for this document to be matched exactly for use with MongoDB’s $ operator.
235 236 237 |
# File 'lib/mongoid/atomic.rb', line 235 def atomic_selector atomic_paths.selector end |
#atomic_sets ⇒ Hash
Get all the attributes that need to be set.
247 248 249 |
# File 'lib/mongoid/atomic.rb', line 247 def atomic_sets updateable? ? setters : settable? ? { atomic_path => as_document } : {} end |
#atomic_unsets ⇒ Array<Hash>
Get all the attributes that need to be unset.
259 260 261 262 263 264 265 266 267 268 269 |
# File 'lib/mongoid/atomic.rb', line 259 def atomic_unsets unsets = [] delayed_atomic_unsets.each_pair do |name, docs| path = nil docs.each do |doc| path ||= doc.flag_as_destroyed end unsets.push(path || name) end unsets end |
#atomic_updates(use_indexes = false) ⇒ Hash Also known as: _updates
MongoDB does not allow “conflicting modifications” to be performed in a single operation. Conflicting modifications are detected by the ‘haveConflictingMod’ function in MongoDB. Examination of the code suggests that two modifications (a $set and a $pushAll, for example) conflict if:
(1) the key paths being modified are equal.
(2) one key path is a prefix of the other.
So a $set of ‘addresses.0.street’ will conflict with a $pushAll to ‘addresses’, and we will need to split our update into two pieces. We do not, however, attempt to match MongoDB’s logic exactly. Instead, we assume that two updates conflict if the first component of the two key paths matches.
Get all the atomic updates that need to happen for the current Document
. This includes all changes that need to happen in the entire hierarchy that exists below where the save call was made.
128 129 130 131 132 133 134 135 136 137 |
# File 'lib/mongoid/atomic.rb', line 128 def atomic_updates(use_indexes = false) process_flagged_destroys mods = Modifiers.new generate_atomic_updates(mods, self) _children.each do |child| child.process_flagged_destroys generate_atomic_updates(mods, child) end mods end |
#delayed_atomic_pulls ⇒ Hash
Get a hash of atomic pulls that are pending.
291 292 293 |
# File 'lib/mongoid/atomic.rb', line 291 def delayed_atomic_pulls @delayed_atomic_pulls ||= {} end |
#delayed_atomic_sets ⇒ Hash
Get all the atomic sets that have had their saves delayed.
279 280 281 |
# File 'lib/mongoid/atomic.rb', line 279 def delayed_atomic_sets @delayed_atomic_sets ||= {} end |
#delayed_atomic_unsets ⇒ Hash
Get the delayed atomic unsets.
303 304 305 |
# File 'lib/mongoid/atomic.rb', line 303 def delayed_atomic_unsets @delayed_atomic_unsets ||= {} end |
#flag_as_destroyed ⇒ String
Flag the document as destroyed and return the atomic path.
315 316 317 318 319 |
# File 'lib/mongoid/atomic.rb', line 315 def flag_as_destroyed self.destroyed = true self.flagged_for_destroy = false atomic_path end |
#flagged_destroys ⇒ Array<Proc>
Get the flagged destroys.
329 330 331 |
# File 'lib/mongoid/atomic.rb', line 329 def flagged_destroys @flagged_destroys ||= [] end |
#process_flagged_destroys ⇒ Array
Process all the pending flagged destroys from nested attributes.
341 342 343 344 345 346 347 348 |
# File 'lib/mongoid/atomic.rb', line 341 def process_flagged_destroys _assigning do flagged_destroys.each do |block| block.call end end flagged_destroys.clear end |