class SwitchConnection::Proxy

Constants

AVAILABLE_MODES
DEFAULT_MODE

Attributes

initial_name[R]

Public Class Methods

new(name) click to toggle source
# File lib/switch_connection/proxy.rb, line 11
def initialize(name)
  @initial_name = name
  @current_name = name
  define_master_model(name)
  define_slave_model(name)
  @global_mode = DEFAULT_MODE
end

Public Instance Methods

cache(&block) click to toggle source
# File lib/switch_connection/proxy.rb, line 171
def cache(&block)
  r = with_slave { model_for_connection }
  w = with_master { model_for_connection }
  r.cache { w.cache(&block) }
end
connected?() click to toggle source
# File lib/switch_connection/proxy.rb, line 167
def connected?
  model_for_connection.connected?
end
connection() click to toggle source
# File lib/switch_connection/proxy.rb, line 163
def connection
  model_for_connection.connection
end
db_specific(db_name) click to toggle source
# File lib/switch_connection/proxy.rb, line 47
def db_specific(db_name)
  base_config = ::ActiveRecord::Base.configurations.fetch(SwitchConnection.config.env)
  return base_config if db_name == :default

  db_name.to_s.split('.').inject(base_config) { |h, n| h[n] }
end
define_master_model(name) click to toggle source
# File lib/switch_connection/proxy.rb, line 19
def define_master_model(name)
  model_name = SwitchConnection.config.master_model_name(name)
  if model_name
    model = Class.new(ActiveRecord::Base)
    Proxy.const_set(model_name, model)
    master_database_name = SwitchConnection.config.master_database_name(name)
    model.establish_connection(db_specific(master_database_name))
    model
  else
    ActiveRecord::Base
  end
end
define_slave_model(name) click to toggle source
# File lib/switch_connection/proxy.rb, line 32
def define_slave_model(name)
  return unless SwitchConnection.config.slave_exist?(name)

  slave_count = SwitchConnection.config.slave_count(name)
  (0..(slave_count - 1)).map do |index|
    model_name = SwitchConnection.config.slave_mode_name(name, index)
    next ActiveRecord::Base unless model_name

    model = Class.new(ActiveRecord::Base)
    Proxy.const_set(model_name, model)
    model.establish_connection(db_specific(SwitchConnection.config.slave_database_name(name, index)))
    model
  end
end
master!() click to toggle source
# File lib/switch_connection/proxy.rb, line 91
def master!
  if thread_local_mode
    self.thread_local_mode = :master
  else
    @global_mode = :master
  end
end
master?() click to toggle source
# File lib/switch_connection/proxy.rb, line 99
def master?
  mode == :master
end
mode() click to toggle source
# File lib/switch_connection/proxy.rb, line 63
def mode
  thread_local_mode || @global_mode
end
model_for_connection() click to toggle source
# File lib/switch_connection/proxy.rb, line 148
def model_for_connection
  ProxyRepository.checkout(@current_name) # Ensure the target proxy is created
  model_name = SwitchConnection.config.model_name(@current_name, mode)
  if model_name
    Proxy.const_get(model_name)
  elsif mode == :slave
    # When only master is specified, re-use master connection.
    with_master do
      model_for_connection
    end
  else
    ActiveRecord::Base
  end
end
reset_name!() click to toggle source
# File lib/switch_connection/proxy.rb, line 144
def reset_name!
  @current_name = @initial_name
end
slave!() click to toggle source
# File lib/switch_connection/proxy.rb, line 79
def slave!
  if thread_local_mode
    self.thread_local_mode = :slave
  else
    @global_mode = :slave
  end
end
slave?() click to toggle source
# File lib/switch_connection/proxy.rb, line 87
def slave?
  mode == :slave
end
switch_connection_level() click to toggle source
# File lib/switch_connection/proxy.rb, line 71
def switch_connection_level
  Thread.current[:"switch_point_#{@current_name}_level"] || 0
end
switch_connection_level=(level) click to toggle source
# File lib/switch_connection/proxy.rb, line 67
def switch_connection_level=(level)
  Thread.current[:"switch_point_#{@current_name}_level"] = level
end
switch_name(new_name, &block) click to toggle source
# File lib/switch_connection/proxy.rb, line 130
def switch_name(new_name, &block)
  if block
    begin
      old_name = @current_name
      @current_name = new_name
      block.call
    ensure
      @current_name = old_name
    end
  else
    @current_name = new_name
  end
end
switch_top_level_connection?() click to toggle source
# File lib/switch_connection/proxy.rb, line 75
def switch_top_level_connection?
  switch_connection_level.zero?
end
thread_local_mode() click to toggle source
# File lib/switch_connection/proxy.rb, line 54
def thread_local_mode
  Thread.current[:"switch_point_#{@current_name}_mode"]
end
uncached(&block) click to toggle source
# File lib/switch_connection/proxy.rb, line 177
def uncached(&block)
  r = with_slave { model_for_connection }
  w = with_master { model_for_connection }
  r.uncached { w.uncached(&block) }
end
with_master(&block) click to toggle source
# File lib/switch_connection/proxy.rb, line 107
def with_master(&block)
  with_mode(:master, &block)
end
with_mode(new_mode, &block) click to toggle source
# File lib/switch_connection/proxy.rb, line 111
def with_mode(new_mode, &block)
  unless AVAILABLE_MODES.include?(new_mode)
    self.switch_connection_level += 1
    raise ArgumentError.new("Unknown mode: #{new_mode}")
  end

  saved_mode = thread_local_mode
  if new_mode == :slave && switch_top_level_connection?
    self.thread_local_mode = :slave
  elsif new_mode == :master
    self.thread_local_mode = :master
  end
  self.switch_connection_level += 1
  block.call
ensure
  self.thread_local_mode = saved_mode
  self.switch_connection_level -= 1
end
with_slave(&block) click to toggle source
# File lib/switch_connection/proxy.rb, line 103
def with_slave(&block)
  with_mode(:slave, &block)
end

Private Instance Methods

thread_local_mode=(mode) click to toggle source
# File lib/switch_connection/proxy.rb, line 58
def thread_local_mode=(mode)
  Thread.current[:"switch_point_#{@current_name}_mode"] = mode
end