Module: DataMapper::Model::Scope

Included in:
DataMapper::Model
Defined in:
lib/dm-core/model/scope.rb

Overview

Module with query scoping functionality.

Scopes are implemented using simple array based stack that is thread local. Default scope can be set on a per repository basis.

Scopes are merged as new queries are nested. It is also possible to get exclusive scope access using with_exclusive_scope

Instance Method Summary collapse

Instance Method Details

#current_scopeObject

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.



34
35
36
# File 'lib/dm-core/model/scope.rb', line 34

def current_scope
  scope_stack.last || default_scope(repository.name)
end

#default_scope(repository_name = default_repository_name) ⇒ 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.



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/dm-core/model/scope.rb', line 14

def default_scope(repository_name = default_repository_name)
  @default_scope ||= {}

  default_repository_name = self.default_repository_name

  @default_scope[repository_name] ||= if repository_name == default_repository_name
    {}
  else
    default_scope(default_repository_name).dup
  end
end

#queryObject

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.

Returns query on top of scope stack



29
30
31
# File 'lib/dm-core/model/scope.rb', line 29

def query
  repository.new_query(self, current_scope).freeze
end

#scope_stackObject (protected)

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.

Initializes (if necessary) and returns current scope stack



81
82
83
84
# File 'lib/dm-core/model/scope.rb', line 81

def scope_stack
  scope_stack_for = Thread.current[:dm_scope_stack] ||= {}
  scope_stack_for[object_id] ||= []
end

#with_exclusive_scope(query) ⇒ Object (protected)

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.

Pushes given query on top of scope stack and yields given block, then pops the stack. During block execution queries previously pushed onto the stack have no effect.



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/dm-core/model/scope.rb', line 62

def with_exclusive_scope(query)
  query = if query.kind_of?(Hash)
    repository.new_query(self, query)
  else
    query.dup
  end

  scope_stack = self.scope_stack
  scope_stack << query.options

  begin
    yield query.freeze
  ensure
    scope_stack.pop
  end
end

#with_scope(query) ⇒ Object (protected)

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.

Pushes given query on top of the stack



45
46
47
48
49
50
51
52
53
54
# File 'lib/dm-core/model/scope.rb', line 45

def with_scope(query)
  options = if query.kind_of?(Hash)
    query
  else
    query.options
  end

  # merge the current scope with the passed in query
  with_exclusive_scope(self.query.merge(options)) { |*block_args| yield(*block_args) }
end