Module: Mongoid::Atomic
Relationships & Source Files | |
Namespace Children | |
Modules:
| |
Classes:
| |
Extension / Inclusion / Inheritance Descendants | |
Included In:
| |
Super Chains via Extension / Inclusion / Inheritance | |
Class Chain:
self,
ActiveSupport::Concern
|
|
Defined in: | lib/mongoid/atomic.rb, lib/mongoid/atomic/modifiers.rb, lib/mongoid/atomic/paths/embedded.rb, lib/mongoid/atomic/paths/root.rb, lib/mongoid/atomic/paths/embedded/many.rb, lib/mongoid/atomic/paths/embedded/one.rb |
Overview
This module contains the logic for supporting atomic operations against the database.
Constant Summary
-
UPDATES =
# File 'lib/mongoid/atomic.rb', line 12%i[ atomic_array_pushes atomic_array_pulls atomic_array_add_to_sets atomic_pulls delayed_atomic_sets delayed_atomic_pulls delayed_atomic_unsets ].freeze
Instance Method Summary
-
#_updates(_use_indexes = false)
Alias for #atomic_updates.
-
#add_atomic_pull(document)
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_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.
-
#generate_atomic_updates(mods, doc)
private
Generates the atomic updates in the correct order.
-
#reset_atomic_updates!
private
Clears all pending atomic updates.
DSL Calls
included
[ GitHub ]22 23 24 25 26
# File 'lib/mongoid/atomic.rb', line 22
included do # When MongoDB finally fully implements the positional operator, we can # get rid of all indexing related code in Mongoid. attr_accessor :_index end
Instance Method Details
#_updates(_use_indexes = false)
Alias for #atomic_updates.
# File 'lib/mongoid/atomic.rb', line 129
alias _updates atomic_updates
#add_atomic_pull(document)
Add the document as an atomic pull.
# File 'lib/mongoid/atomic.rb', line 34
def add_atomic_pull(document) document.flagged_for_destroy = true key = document.association_name.to_s delayed_atomic_pulls[key] ||= [] delayed_atomic_pulls[key] << document end
#add_atomic_unset(document) ⇒ Array<Document>
Add an atomic unset for the document.
# File 'lib/mongoid/atomic.rb', line 49
def add_atomic_unset(document) document.flagged_for_destroy = true key = document.association_name.to_s delayed_atomic_unsets[key] ||= [] delayed_atomic_unsets[key] << document end
#atomic_array_add_to_sets ⇒ Hash
For array fields these are the unique adds that need to happen.
# File 'lib/mongoid/atomic.rb', line 92
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.
# File 'lib/mongoid/atomic.rb', line 82
def atomic_array_pulls @atomic_array_pulls ||= {} end
#atomic_array_pushes ⇒ Hash
For array fields these are the pushes that need to happen.
# File 'lib/mongoid/atomic.rb', line 72
def atomic_array_pushes @atomic_array_pushes ||= {} end
#atomic_attribute_name(name) ⇒ String
Returns path of the attribute for modification
# File 'lib/mongoid/atomic.rb', line 62
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.
# File 'lib/mongoid/atomic.rb', line 139
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.
# File 'lib/mongoid/atomic.rb', line 150
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.
# File 'lib/mongoid/atomic.rb', line 161
def atomic_path atomic_paths.path end
#atomic_paths ⇒ Object
Get the atomic paths utility for this document.
#atomic_position ⇒ String
Returns the positional operator of this document for modification.
# File 'lib/mongoid/atomic.rb', line 171
def atomic_position atomic_paths.position end
#atomic_pulls ⇒ Array<Hash>
Get all the attributes that need to be pulled.
# File 'lib/mongoid/atomic.rb', line 199
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.
# File 'lib/mongoid/atomic.rb', line 218
def atomic_pushes pushable? ? { atomic_position => as_attributes } : {} end
#atomic_sets ⇒ Hash
Get all the attributes that need to be set.
# File 'lib/mongoid/atomic.rb', line 228
def atomic_sets if updateable? setters elsif settable? { atomic_path => as_attributes } else {} end end
#atomic_unsets ⇒ Array<Hash>
Get all the attributes that need to be unset.
# File 'lib/mongoid/atomic.rb', line 244
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 $push with $each, 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 $push and $each 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.
# File 'lib/mongoid/atomic.rb', line 119
def atomic_updates(_use_indexes = false) process_flagged_destroys mods = Modifiers.new generate_atomic_updates(mods, self) _descendants.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.
# File 'lib/mongoid/atomic.rb', line 272
def delayed_atomic_pulls @delayed_atomic_pulls ||= {} end
#delayed_atomic_sets ⇒ Hash
Get all the atomic sets that have had their saves delayed.
# File 'lib/mongoid/atomic.rb', line 262
def delayed_atomic_sets @delayed_atomic_sets ||= {} end
#delayed_atomic_unsets ⇒ Hash
Get the delayed atomic unsets.
# File 'lib/mongoid/atomic.rb', line 282
def delayed_atomic_unsets @delayed_atomic_unsets ||= {} end
#flag_as_destroyed ⇒ String
Flag the document as destroyed and return the atomic path.
# File 'lib/mongoid/atomic.rb', line 292
def flag_as_destroyed self.destroyed = true self.flagged_for_destroy = false atomic_path end
#flagged_destroys ⇒ Array<Proc
>
Get the flagged destroys.
# File 'lib/mongoid/atomic.rb', line 304
def flagged_destroys @flagged_destroys ||= [] end
#generate_atomic_updates(mods, doc) (private)
Generates the atomic updates in the correct order.
# File 'lib/mongoid/atomic.rb', line 337
def generate_atomic_updates(mods, doc) mods.unset(doc.atomic_unsets) mods.pull(doc.atomic_pulls) mods.set(doc.atomic_sets) mods.set(doc.delayed_atomic_sets) mods.push(doc.atomic_pushes) mods.push(doc.atomic_array_pushes) mods.add_to_set(doc.atomic_array_add_to_sets) mods.pull_all(doc.atomic_array_pulls) end
#process_flagged_destroys ⇒ Array
Process all the pending flagged destroys from nested attributes.
# File 'lib/mongoid/atomic.rb', line 314
def process_flagged_destroys _assigning do flagged_destroys.each(&:call) end flagged_destroys.clear end
#reset_atomic_updates! (private)
Clears all pending atomic updates.
# File 'lib/mongoid/atomic.rb', line 324
def reset_atomic_updates! Atomic::UPDATES.each do |update| send(update).clear end end