Module: Mongoid::Threaded

Extended by:
Threaded
Included in:
Threaded
Defined in:
lib/mongoid/threaded.rb,
lib/mongoid/threaded/lifecycle.rb

Overview

This module contains logic for easy access to objects that have a lifecycle on the current thread.

Defined Under Namespace

Modules: Lifecycle

Constant Summary collapse

DATABASE_OVERRIDE_KEY =
"[mongoid]:db-override"
CLIENTS_KEY =

Constant for the key to store clients.

"[mongoid]:clients"
CLIENT_OVERRIDE_KEY =

The key to override the client.

"[mongoid]:client-override"
CURRENT_SCOPE_KEY =

The key for the current thread’s scope stack.

"[mongoid]:current-scope"
AUTOSAVES_KEY =
"[mongoid]:autosaves"
VALIDATIONS_KEY =
"[mongoid]:validations"
STACK_KEYS =
Hash.new do |hash, key|
  hash[key] = "[mongoid]:#{key}-stack"
end
SESSIONS_KEY =

The key for the current thread’s sessions.

"[mongoid]:sessions"
MODIFIED_DOCUMENTS_KEY =

The key for storing documents modified inside transactions.

"[mongoid]:modified-documents"
BIND =
'bind'.freeze
ASSIGN =
'assign'.freeze
BUILD =
'build'.freeze
LOAD =
'load'.freeze
CREATE =
'create'.freeze

Instance Method Summary collapse

Instance Method Details

#add_modified_document(session, document) ⇒ Object

Store a reference to the document that was modified inside a transaction associated with the session.

Parameters:

  • session (Mongo::Session)

    Session in scope of which the document was modified.

  • document (Mongoid::Document)

    Mongoid document that was modified.



365
366
367
368
369
# File 'lib/mongoid/threaded.rb', line 365

def add_modified_document(session, document)
  if session&.in_transaction?
    modified_documents[session] << document
  end
end

#autosaved?(document) ⇒ true | false

Is the document autosaved on the current thread?

Examples:

Is the document autosaved?

Threaded.autosaved?(doc)

Parameters:

  • document (Document)

    The document to check.

Returns:

  • (true | false)

    If the document is autosaved.



265
266
267
# File 'lib/mongoid/threaded.rb', line 265

def autosaved?(document)
  autosaves_for(document.class).include?(document._id)
end

#autosavesHash

Get all autosaves on the current thread.

Examples:

Get all autosaves.

Threaded.autosaves

Returns:

  • (Hash)

    The current autosaves.



287
288
289
# File 'lib/mongoid/threaded.rb', line 287

def autosaves
  Thread.current[AUTOSAVES_KEY] ||= {}
end

#autosaves_for(klass) ⇒ Array

Get all autosaves on the current thread for the class.

Examples:

Get all autosaves.

Threaded.autosaves_for(Person)

Parameters:

  • klass (Class)

    The class to check.

Returns:

  • (Array)

    The current autosaves.



309
310
311
# File 'lib/mongoid/threaded.rb', line 309

def autosaves_for(klass)
  autosaves[klass] ||= []
end

#begin_autosave(document) ⇒ Object

Begin autosaving a document on the current thread.

Examples:

Begin autosave.

Threaded.begin_autosave(doc)

Parameters:

  • document (Document)

    The document to autosave.



113
114
115
# File 'lib/mongoid/threaded.rb', line 113

def begin_autosave(document)
  autosaves_for(document.class).push(document._id)
end

#begin_execution(name) ⇒ true

Begin entry into a named thread local stack.

Examples:

Begin entry into the stack.

Threaded.begin_execution(:create)

Parameters:

  • name (String)

    The name of the stack

Returns:

  • (true)

    True.



45
46
47
# File 'lib/mongoid/threaded.rb', line 45

def begin_execution(name)
  stack(name).push(true)
end

#begin_validate(document) ⇒ Object

Begin validating a document on the current thread.

Examples:

Begin validation.

Threaded.begin_validate(doc)

Parameters:

  • document (Document)

    The document to validate.



123
124
125
# File 'lib/mongoid/threaded.rb', line 123

def begin_validate(document)
  validations_for(document.class).push(document._id)
end

#begin_without_default_scope(klass) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Begin suppressing default scopes for given model on the current thread.

Examples:

Begin without default scope stack.

Threaded.begin_without_default_scope(klass)

Parameters:

  • klass (Class)

    The model to suppress default scoping on.



155
156
157
# File 'lib/mongoid/threaded.rb', line 155

def begin_without_default_scope(klass)
  stack(:without_default_scope).push(klass)
end

#clear_modified_documents(session) ⇒ Set<Mongoid::Document>

Clears the set of modified documents for the given session, and return the content of the set before the clearance.

Parameters:

  • session (Mongo::Session)

    Session for which the modified documents set should be cleared.

Returns:

  • (Set<Mongoid::Document>)

    Collection of modified documents before it was cleared.



378
379
380
381
382
# File 'lib/mongoid/threaded.rb', line 378

def clear_modified_documents(session)
  modified_documents[session].dup
ensure
  modified_documents[session].clear
end

#clear_session(client: nil) ⇒ nil

Note:

For backward compatibility it is allowed to call this method without

Clear the cached session for this thread for a client.

specifying ‘client` parameter.

Parameters:

  • client (Mongo::Client | nil) (defaults to: nil)

    The client to clear the session for.

Returns:

  • (nil)


355
356
357
# File 'lib/mongoid/threaded.rb', line 355

def clear_session(client: nil)
  sessions.delete(client.object_id)&.end_session
end

#client_overrideString | Symbol

Get the global client override.

Examples:

Get the global client override.

Threaded.client_override

Returns:

  • (String | Symbol)

    The override.



177
178
179
# File 'lib/mongoid/threaded.rb', line 177

def client_override
  Thread.current[CLIENT_OVERRIDE_KEY]
end

#client_override=(name) ⇒ String | Symbol

Set the global client override.

Examples:

Set the global client override.

Threaded.client_override = :testing

Parameters:

  • name (String | Symbol)

    The global override name.

Returns:

  • (String | Symbol)

    The override.



189
190
191
# File 'lib/mongoid/threaded.rb', line 189

def client_override=(name)
  Thread.current[CLIENT_OVERRIDE_KEY] = name
end

#current_scope(klass = nil) ⇒ Criteria

Get the current Mongoid scope.

Examples:

Get the scope.

Threaded.current_scope(klass)
Threaded.current_scope

Parameters:

  • klass (Klass) (defaults to: nil)

    The class type of the scope.

Returns:



202
203
204
205
206
207
208
209
210
# File 'lib/mongoid/threaded.rb', line 202

def current_scope(klass = nil)
  if klass && Thread.current[CURRENT_SCOPE_KEY].respond_to?(:keys)
    Thread.current[CURRENT_SCOPE_KEY][
        Thread.current[CURRENT_SCOPE_KEY].keys.find { |k| k <= klass }
    ]
  else
    Thread.current[CURRENT_SCOPE_KEY]
  end
end

#current_scope=(scope) ⇒ Criteria

Set the current Mongoid scope.

Examples:

Set the scope.

Threaded.current_scope = scope

Parameters:

  • scope (Criteria)

    The current scope.

Returns:



220
221
222
# File 'lib/mongoid/threaded.rb', line 220

def current_scope=(scope)
  Thread.current[CURRENT_SCOPE_KEY] = scope
end

#database_overrideString | Symbol

Get the global database override.

Examples:

Get the global database override.

Threaded.database_override

Returns:

  • (String | Symbol)

    The override.



55
56
57
# File 'lib/mongoid/threaded.rb', line 55

def database_override
  Thread.current[DATABASE_OVERRIDE_KEY]
end

#database_override=(name) ⇒ String | Symbol

Set the global database override.

Examples:

Set the global database override.

Threaded.database_override = :testing

Parameters:

  • name (String | Symbol)

    The global override name.

Returns:

  • (String | Symbol)

    The override.



67
68
69
# File 'lib/mongoid/threaded.rb', line 67

def database_override=(name)
  Thread.current[DATABASE_OVERRIDE_KEY] = name
end

#executing?(name) ⇒ true

Are in the middle of executing the named stack

Examples:

Are we in the stack execution?

Threaded.executing?(:create)

Parameters:

  • name (Symbol)

    The name of the stack

Returns:

  • (true)

    If the stack is being executed.



79
80
81
# File 'lib/mongoid/threaded.rb', line 79

def executing?(name)
  !stack(name).empty?
end

#exit_autosave(document) ⇒ Object

Exit autosaving a document on the current thread.

Examples:

Exit autosave.

Threaded.exit_autosave(doc)

Parameters:

  • document (Document)

    The document to autosave.



133
134
135
# File 'lib/mongoid/threaded.rb', line 133

def exit_autosave(document)
  autosaves_for(document.class).delete_one(document._id)
end

#exit_execution(name) ⇒ true

Exit from a named thread local stack.

Examples:

Exit from the stack.

Threaded.exit_execution(:create)

Parameters:

  • name (Symbol)

    The name of the stack

Returns:

  • (true)

    True.



91
92
93
# File 'lib/mongoid/threaded.rb', line 91

def exit_execution(name)
  stack(name).pop
end

#exit_validate(document) ⇒ Object

Exit validating a document on the current thread.

Examples:

Exit validation.

Threaded.exit_validate(doc)

Parameters:

  • document (Document)

    The document to validate.



143
144
145
# File 'lib/mongoid/threaded.rb', line 143

def exit_validate(document)
  validations_for(document.class).delete_one(document._id)
end

#exit_without_default_scope(klass) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Exit suppressing default scopes for given model on the current thread.

Examples:

Exit without default scope stack.

Threaded.exit_without_default_scope(klass)

Parameters:

  • klass (Class)

    The model to unsuppress default scoping on.



167
168
169
# File 'lib/mongoid/threaded.rb', line 167

def exit_without_default_scope(klass)
  stack(:without_default_scope).delete(klass)
end

#get_session(client: nil) ⇒ Mongo::Session | nil

Note:

For backward compatibility it is allowed to call this method without

Get the cached session for this thread for a client.

specifying ‘client` parameter.

Parameters:

  • client (Mongo::Client | nil) (defaults to: nil)

    The client to cache the session for.

Returns:

  • (Mongo::Session | nil)

    The session cached on this thread or nil.



343
344
345
# File 'lib/mongoid/threaded.rb', line 343

def get_session(client: nil)
  sessions[client.object_id]
end

#modified_documentsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



390
391
392
393
394
# File 'lib/mongoid/threaded.rb', line 390

def modified_documents
  Thread.current[MODIFIED_DOCUMENTS_KEY] ||= Hash.new do |h, k|
    h[k] = Set.new
  end
end

#sessionsObject

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.



385
386
387
# File 'lib/mongoid/threaded.rb', line 385

def sessions
  Thread.current[SESSIONS_KEY] ||= {}
end

#set_current_scope(scope, klass) ⇒ Criteria

Set the current Mongoid scope. Safe for multi-model scope chaining.

Examples:

Set the scope.

Threaded.current_scope(scope, klass)

Parameters:

  • scope (Criteria)

    The current scope.

  • klass (Class)

    The current model class.

Returns:



233
234
235
236
237
238
239
240
241
242
243
# File 'lib/mongoid/threaded.rb', line 233

def set_current_scope(scope, klass)
  if scope.nil?
    if Thread.current[CURRENT_SCOPE_KEY]
      Thread.current[CURRENT_SCOPE_KEY].delete(klass)
      Thread.current[CURRENT_SCOPE_KEY] = nil if Thread.current[CURRENT_SCOPE_KEY].empty?
    end
  else
    Thread.current[CURRENT_SCOPE_KEY] ||= {}
    Thread.current[CURRENT_SCOPE_KEY][klass] = scope
  end
end

#set_session(session, client: nil) ⇒ Object

Note:

For backward compatibility it is allowed to call this method without

Cache a session for this thread for a client.

specifying ‘client` parameter.

Parameters:

  • session (Mongo::Session)

    The session to save.

  • client (Mongo::Client | nil) (defaults to: nil)

    The client to cache the session for.



331
332
333
# File 'lib/mongoid/threaded.rb', line 331

def set_session(session, client: nil)
  sessions[client.object_id] = session
end

#stack(name) ⇒ Array

Get the named stack.

Examples:

Get a stack by name

Threaded.stack(:create)

Parameters:

  • name (Symbol)

    The name of the stack

Returns:

  • (Array)

    The stack.



103
104
105
# File 'lib/mongoid/threaded.rb', line 103

def stack(name)
  Thread.current[STACK_KEYS[name]] ||= []
end

#validated?(document) ⇒ true | false

Is the document validated on the current thread?

Examples:

Is the document validated?

Threaded.validated?(doc)

Parameters:

  • document (Document)

    The document to check.

Returns:

  • (true | false)

    If the document is validated.



277
278
279
# File 'lib/mongoid/threaded.rb', line 277

def validated?(document)
  validations_for(document.class).include?(document._id)
end

#validationsHash

Get all validations on the current thread.

Examples:

Get all validations.

Threaded.validations

Returns:

  • (Hash)

    The current validations.



297
298
299
# File 'lib/mongoid/threaded.rb', line 297

def validations
  Thread.current[VALIDATIONS_KEY] ||= {}
end

#validations_for(klass) ⇒ Array

Get all validations on the current thread for the class.

Examples:

Get all validations.

Threaded.validations_for(Person)

Parameters:

  • klass (Class)

    The class to check.

Returns:

  • (Array)

    The current validations.



320
321
322
# File 'lib/mongoid/threaded.rb', line 320

def validations_for(klass)
  validations[klass] ||= []
end

#without_default_scope?(klass) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Is the given klass’ default scope suppressed on the current thread?

Examples:

Is the given klass’ default scope suppressed?

Threaded.without_default_scope?(klass)

Parameters:

  • klass (Class)

    The model to check for default scope suppression.

Returns:



253
254
255
# File 'lib/mongoid/threaded.rb', line 253

def without_default_scope?(klass)
  stack(:without_default_scope).include?(klass)
end