class Innkeeper::Adapters::AbstractAdapter

Attributes

current[R]

Public Class Methods

new() click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 9
def initialize
  reset
rescue Innkeeper::TenantNotFound
  puts "WARN: Unable to connect to default tenant"
end

Public Instance Methods

config_for(tenant) click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 94
def config_for(tenant)
  return tenant if tenant.is_a?(Hash)

  decorated_tenant = decorate(tenant)
  Innkeeper.tenant_resolver.resolve(decorated_tenant)
end
connection_specification_name() click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 120
def connection_specification_name
  if !defined?(@connection_specification_name) || @connection_specification_name.nil?
    innkeeper_spec_name = Thread.current[:_innkeeper_connection_specification_name]
    return innkeeper_spec_name ||
      (self == ActiveRecord::Base ? "primary" : superclass.connection_specification_name)
  end
  @connection_specification_name
end
connection_switch!(config, without_keys: []) click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 136
def connection_switch!(config, without_keys: [])
  config = config.reject{ |k, _| without_keys.include?(k) }

  config.merge!(name: connection_specification_name(config))

  unless Innkeeper.connection_handler.retrieve_connection_pool(config[:name])
    Innkeeper.connection_handler.establish_connection(config)
  end

  Thread.current[:_innkeeper_connection_specification_name] = config[:name]
  simple_switch(config) if config[:database] || config[:schema_search_path]
end
create(tenant) { || ... } click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 28
def create(tenant)
  run_callbacks :create do
    begin
      previous_tenant = @current
      config = config_for(tenant)
      difference = current_difference_from(config)

      if difference[:host]
        connection_switch!(config, without_keys: [:database, :schema_search_path])
      end

      create_tenant!(config)
      simple_switch(config)
      @current = tenant

      import_database_schema
      seed_data if Innkeeper.seed_after_create

      yield if block_given?
    ensure
      switch!(previous_tenant) rescue reset
    end
  end
end
current_difference_from(config) click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 131
def current_difference_from(config)
  current_config = config_for(@current)
  config.select{ |k, v| current_config[k] != v }
end
decorate(tenant) click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 101
def decorate(tenant)
  decorator = Innkeeper.tenant_decorator
  decorator ? decorator.call(tenant) : tenant
end
drop(tenant) click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 53
def drop(tenant)
  previous_tenant = @current

  config = config_for(tenant)
  difference = current_difference_from(config)

  if difference[:host]
    connection_switch!(config, without_keys: [:database])
  end

  unless database_exists?(config[:database])
    raise TenantNotFound, "Error while dropping database #{config[:database]} for tenant #{tenant}"
  end

  Innkeeper.connection.drop_database(config[:database])

  @current = tenant
ensure
  switch!(previous_tenant) rescue reset
end
import_database_schema() click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 149
def import_database_schema
  ActiveRecord::Schema.verbose = false

  load_or_abort(Innkeeper.database_schema_file) if Innkeeper.database_schema_file
end
load_or_abort(file) click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 159
def load_or_abort(file)
  if File.exist?(file)
    load(file)
  else
    abort %{#{file} doesn't exist yet}
  end
end
process_excluded_models() click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 106
def process_excluded_models
  excluded_config = config_for(Innkeeper.default_tenant).merge(name: :_innkeeper_excluded)
  Innkeeper.connection_handler.establish_connection(excluded_config)

  Innkeeper.excluded_models.each do |excluded_model|
    # user mustn't have overridden `connection_specification_name`
    # cattr_accessor in model
    excluded_model.constantize.connection_specification_name = :_innkeeper_excluded
  end
end
raise_connect_error!(tenant, exception) click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 167
def raise_connect_error!(tenant, exception)
  raise TenantNotFound, "Error while connecting to tenant #{tenant}: #{exception.message}"
end
reset() click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 15
def reset
  switch!(Innkeeper.default_tenant)
end
seed_data() click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 155
def seed_data
  silence_warnings{ load_or_abort(Innkeeper.seed_data_file) } if Innkeeper.seed_data_file
end
setup_connection_specification_name() click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 117
def setup_connection_specification_name
  Innkeeper.connection_class.connection_specification_name = nil
  Innkeeper.connection_class.instance_eval do
    def connection_specification_name
      if !defined?(@connection_specification_name) || @connection_specification_name.nil?
        innkeeper_spec_name = Thread.current[:_innkeeper_connection_specification_name]
        return innkeeper_spec_name ||
          (self == ActiveRecord::Base ? "primary" : superclass.connection_specification_name)
      end
      @connection_specification_name
    end
  end
end
switch(tenant = nil) { || ... } click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 19
def switch(tenant = nil)
  previous_tenant = @current
  switch!(tenant)

  yield
ensure
  switch!(previous_tenant) rescue reset
end
switch!(tenant) click to toggle source
# File lib/innkeeper/adapters/abstract_adapter.rb, line 74
def switch!(tenant)
  run_callbacks :switch do
    return reset if tenant.nil?

    config = config_for(tenant)

    if Innkeeper.force_reconnect_on_switch
      connection_switch!(config)
    else
      switch_tenant(config)
    end

    @current = tenant

    Innkeeper.connection.clear_query_cache

    tenant
  end
end