Module: Mongoid::Atomic

Extended by:
ActiveSupport::Concern
Included in:
Composable, Contextual::Mongo
Defined in:
build/mongoid-master/lib/mongoid/atomic.rb,
build/mongoid-master/lib/mongoid/atomic/modifiers.rb,
build/mongoid-master/lib/mongoid/atomic/paths/root.rb,
build/mongoid-master/lib/mongoid/atomic/paths/embedded.rb,
build/mongoid-master/lib/mongoid/atomic/paths/embedded/one.rb,
build/mongoid-master/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 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

Instance Method Details

#add_atomic_pull(document) ⇒ Object

Add the document as an atomic pull.

Examples:

Add the atomic pull.

person.add_atomic_pull(address)

Parameters:

  • document (Document)

    The embedded document to pull.

Since:

  • 2.2.0



39
40
41
42
43
44
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 39

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.

Examples:

Add an atomic unset.

document.add_atomic_unset(doc)

Parameters:

  • document (Document)

    The child document.

Returns:

Since:

  • 3.0.0



56
57
58
59
60
61
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 56

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_setsHash

For array fields these are the unique adds that need to happen.

Examples:

Get the array unique adds.

person.atomic_array_add_to_sets

Returns:

  • (Hash)

    The array add_to_sets.

Since:

  • 2.4.0



107
108
109
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 107

def atomic_array_add_to_sets
  @atomic_array_add_to_sets ||= {}
end

#atomic_array_pullsHash

For array fields these are the pulls that need to happen.

Examples:

Get the array pulls.

person.atomic_array_pulls

Returns:

  • (Hash)

    The array pulls.

Since:

  • 2.4.0



95
96
97
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 95

def atomic_array_pulls
  @atomic_array_pulls ||= {}
end

#atomic_array_pushesHash

For array fields these are the pushes that need to happen.

Examples:

Get the array pushes.

person.atomic_array_pushes

Returns:

  • (Hash)

    The array pushes.

Since:

  • 2.4.0



83
84
85
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 83

def atomic_array_pushes
  @atomic_array_pushes ||= {}
end

#atomic_attribute_name(name) ⇒ String

Returns path of the attribute for modification

Examples:

Get path of the attribute

address.atomic_attribute_name(:city)

Returns:

  • (String)

    The path to the document attribute in the database

Since:

  • 3.0.0



71
72
73
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 71

def atomic_attribute_name(name)
  embedded? ? "#{atomic_position}.#{name}" : name
end

#atomic_delete_modifierString

Get the removal modifier for the document. Will be nil on root documents, $unset on embeds_one, $set on embeds_many.

Examples:

Get the removal operator.

name.atomic_delete_modifier

Returns:

  • (String)

    The pull or unset operation.



153
154
155
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 153

def atomic_delete_modifier
  atomic_paths.delete_modifier
end

#atomic_insert_modifierString

Get the insertion modifier for the document. Will be nil on root documents, $set on embeds_one, $push on embeds_many.

Examples:

Get the insert operation.

name.atomic_insert_modifier

Returns:

  • (String)

    The pull or set operator.



164
165
166
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 164

def atomic_insert_modifier
  atomic_paths.insert_modifier
end

#atomic_pathString

Return the path to this Document in JSON notation, used for atomic updates via $set in MongoDB.

Examples:

Get the path to this document.

address.atomic_path

Returns:

  • (String)

    The path to the document in the database.



175
176
177
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 175

def atomic_path
  atomic_paths.path
end

#atomic_pathsObject

Get the atomic paths utility for this document.

Examples:

Get the atomic paths.

document.atomic_paths

Returns:

  • (Object)

    The associated path.

Since:

  • 2.1.0



197
198
199
200
201
202
203
204
205
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 197

def atomic_paths
  @atomic_paths ||= begin
    if _association
      _association.path(self)
    else
      Atomic::Paths::Root.new(self)
    end
  end
end

#atomic_positionString

Returns the positional operator of this document for modification.

Examples:

Get the positional operator.

address.atomic_position

Returns:

  • (String)

    The positional operator with indexes.



185
186
187
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 185

def atomic_position
  atomic_paths.position
end

#atomic_pullsArray<Hash>

Get all the attributes that need to be pulled.

Examples:

Get the pulls.

person.atomic_pulls

Returns:

  • (Array<Hash>)

    The $pullAll operations.

Since:

  • 2.2.0



215
216
217
218
219
220
221
222
223
224
225
226
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 215

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_pushesHash

Get all the push attributes that need to occur.

Examples:

Get the pushes.

person.atomic_pushes

Returns:

  • (Hash)

    The $push and $each operations.

Since:

  • 2.1.0



236
237
238
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 236

def atomic_pushes
  pushable? ? { atomic_position => as_attributes } : {}
end

#atomic_setsHash

Get all the attributes that need to be set.

Examples:

Get the sets.

person.atomic_sets

Returns:

  • (Hash)

    The $set operations.

Since:

  • 2.1.0



248
249
250
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 248

def atomic_sets
  updateable? ? setters : settable? ? { atomic_path => as_attributes } : {}
end

#atomic_unsetsArray<Hash>

Get all the attributes that need to be unset.

Examples:

Get the unsets.

person.atomic_unsets

Returns:

  • (Array<Hash>)

    The $unset operations.

Since:

  • 2.2.0



260
261
262
263
264
265
266
267
268
269
270
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 260

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

Note:

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.

Examples:

Get the updates that need to occur.

person.atomic_updates(children)

Returns:

  • (Hash)

    The updates and their modifiers.

Since:

  • 2.1.0



134
135
136
137
138
139
140
141
142
143
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 134

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_pullsHash

Get a hash of atomic pulls that are pending.

Examples:

Get the atomic pulls.

document.delayed_atomic_pulls

Returns:

  • (Hash)

    name/document pairs.

Since:

  • 2.3.2



292
293
294
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 292

def delayed_atomic_pulls
  @delayed_atomic_pulls ||= {}
end

#delayed_atomic_setsHash

Get all the atomic sets that have had their saves delayed.

Examples:

Get the delayed atomic sets.

person.delayed_atomic_sets

Returns:

  • (Hash)

    The delayed $sets.

Since:

  • 2.3.0



280
281
282
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 280

def delayed_atomic_sets
  @delayed_atomic_sets ||= {}
end

#delayed_atomic_unsetsHash

Get the delayed atomic unsets.

Examples:

Get the delayed atomic unsets.

document.delayed_atomic_unsets

Returns:

  • (Hash)

    The atomic unsets

Since:

  • 3.0.0



304
305
306
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 304

def delayed_atomic_unsets
  @delayed_atomic_unsets ||= {}
end

#flag_as_destroyedString

Flag the document as destroyed and return the atomic path.

Examples:

Flag destroyed and return path.

document.flag_as_destroyed

Returns:

  • (String)

    The atomic path.

Since:

  • 3.0.0



316
317
318
319
320
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 316

def flag_as_destroyed
  self.destroyed = true
  self.flagged_for_destroy = false
  atomic_path
end

#flagged_destroysArray<Proc>

Get the flagged destroys.

Examples:

Get the flagged destroy.

document.flagged_destroys

Returns:

  • (Array<Proc>)

    The flagged destroys.

Since:

  • 3.0.10



330
331
332
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 330

def flagged_destroys
  @flagged_destroys ||= []
end

#process_flagged_destroysArray

Process all the pending flagged destroys from nested attributes.

Examples:

Process all the pending flagged destroys.

document.process_flagged_destroys

Returns:

  • (Array)

    The cleared array.

Since:

  • 3.0.10



342
343
344
345
346
347
# File 'build/mongoid-master/lib/mongoid/atomic.rb', line 342

def process_flagged_destroys
  _assigning do
    flagged_destroys.each(&:call)
  end
  flagged_destroys.clear
end