Class: CaRuby::Database::LazyLoader

Inherits:
Object
  • Object
show all
Defined in:
lib/caruby/database/lazy_loader.rb

Overview

A LazyLoader fetches an association from the database on demand.

Instance Method Summary collapse

Constructor Details

#initialize {|subject, attribute| ... } ⇒ LazyLoader

Creates a new LazyLoader which calls the loader block on the subject.

Yields:

  • (subject, attribute)

    fetches the given subject attribute value from the database

Yield Parameters:

  • subject (Jinx::Resource)

    the domain object whose attribute is to be loaded

  • attribute (Symbol)

    the domain attribute to load



12
13
14
15
16
17
# File 'lib/caruby/database/lazy_loader.rb', line 12

def initialize(&loader)
  @loader = loader
  # the fetch result matcher
  @matcher = FetchedMatcher.new
  @enabled = true
end

Instance Method Details

#disable { ... } ⇒ Object Also known as: suspend

Disables this lazy loader. If the loader is already disabled, then this method is a no-op. Otherwise, if a block is given, then the lazy loader is reenabled after the block is executed.

Yields:

  • the block to call while the loader is disabled

Returns:

  • the result of calling the block if a block is given, nil otherwise



45
46
47
48
49
50
51
52
53
# File 'lib/caruby/database/lazy_loader.rb', line 45

def disable
  reenable = set_disabled
  return unless block_given?
  begin
    yield
  ensure
    set_enabled if reenable
  end
end

#disabled?Boolean

Returns whether this loader is disabled.

Returns:

  • (Boolean)

    whether this loader is disabled



80
81
82
# File 'lib/caruby/database/lazy_loader.rb', line 80

def disabled?
  not @enabled
end

#enable { ... } ⇒ Object Also known as: resume

Enables this lazy loader. If the loader is already enabled, then this method is a no-op. Otherwise, if a block is given, then the lazy loader is redisabled after the block is executed.

Yields:

  • the block to call while the loader is enabled

Returns:

  • the result of calling the block if a block is given, nil otherwise



62
63
64
65
66
67
68
69
70
# File 'lib/caruby/database/lazy_loader.rb', line 62

def enable
  redisable = set_enabled
  return unless block_given?
  begin
    yield
  ensure
    set_disabled if redisable
  end
end

#enabled?Boolean

Returns whether this loader is enabled.

Returns:

  • (Boolean)

    whether this loader is enabled



75
76
77
# File 'lib/caruby/database/lazy_loader.rb', line 75

def enabled?
  @enabled
end

#load(subject, attribute) {|subject, attribute| ... } ⇒ Object

Returns the attribute value loaded from the database.

Parameters:

  • subject (Jinx::Resource)

    the domain object whose attribute is to be loaded

  • the (Symbol)

    domain attribute to load

Yields:

  • (subject, attribute)

    fetches the given subject attribute value from the database

Yield Parameters:

  • subject (Jinx::Resource)

    the domain object whose attribute is to be loaded

  • attribute (Symbol)

    the domain attribute to load

Returns:

  • the attribute value loaded from the database

Raises:

  • (RuntimeError)

    if this loader is disabled



25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/caruby/database/lazy_loader.rb', line 25

def load(subject, attribute)
  if disabled? then raise RuntimeError.new("#{subject.qp} lazy load called on disabled loader") end
  logger.debug { "Lazy-loading #{subject.qp} #{attribute}..." }
  # the current value
  oldval = subject.send(attribute)
  # load the fetched value
  fetched = @loader.call(subject, attribute)
  # nothing to merge if nothing fetched
  return oldval if fetched.nil_or_empty?
  # merge the fetched into the attribute
  logger.debug { "Merging #{subject.qp} fetched #{attribute} value #{fetched.qp}#{' into ' + oldval.qp if oldval}..." }
  matches = @matcher.match(fetched.to_enum, oldval.to_enum, subject, attribute)
  subject.merge_attribute(attribute, fetched, matches)
end