Class: Innkeeper::Adapters::PostgresqlAdapter

Inherits:
AbstractAdapter show all
Defined in:
lib/innkeeper/adapters/postgresql_adapter.rb

Instance Attribute Summary

Attributes inherited from AbstractAdapter

#current

Instance Method Summary collapse

Methods inherited from AbstractAdapter

#config_for, #connection_switch!, #create, #current_difference_from, #decorate, #import_database_schema, #initialize, #load_or_abort, #process_excluded_models, #raise_connect_error!, #reset, #seed_data, #setup_connection_specification_name, #switch, #switch!

Constructor Details

This class inherits a constructor from Innkeeper::Adapters::AbstractAdapter

Instance Method Details

#connection_specification_name(config) ⇒ Object



77
78
79
80
81
82
83
84
# File 'lib/innkeeper/adapters/postgresql_adapter.rb', line 77

def connection_specification_name(config)
  if Innkeeper.pool_per_config
    "_innkeeper_#{config.hash}".to_sym
  else
    host_hash = Digest::MD5.hexdigest(config[:host] || config[:url] || "127.0.0.1")
    "_innkeeper_#{host_hash}_#{config[:adapter]}_#{config[:database]}".to_sym
  end
end

#create_tenant!(config) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/innkeeper/adapters/postgresql_adapter.rb', line 64

def create_tenant!(config)
  unless database_exists?(config[:database])
    Innkeeper.connection.create_database(config[:database], config)
    connection_switch!(config, without_keys: [:schema_search_path])
  end

  schema = first_schema(config[:schema_search_path]) if config[:schema_search_path]

  if schema && !schema_exists?(schema)
    Innkeeper.connection.execute(%{CREATE SCHEMA "#{schema}"})
  end
end

#drop(tenant) ⇒ Object

– ABSTRACT OVERRIDES –

Raises:

  • (NotImplementedError)


8
9
10
11
# File 'lib/innkeeper/adapters/postgresql_adapter.rb', line 8

def drop(tenant)
  raise NotImplementedError,
    "Please use either drop_database or drop_schema for PG adapter"
end

#drop_database(tenant) ⇒ Object

– END ABSTRACT OVERRIDES –



14
15
16
17
# File 'lib/innkeeper/adapters/postgresql_adapter.rb', line 14

def drop_database(tenant)
  # Innkeeper.connection.select_all "select pg_terminate_backend(pg_stat_activity.pid) from pg_stat_activity where datname='#{tenant}' AND state='idle';"
  self.class.superclass.instance_method(:drop).bind(self).call(tenant)
end

#drop_schema(tenant) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/innkeeper/adapters/postgresql_adapter.rb', line 19

def drop_schema(tenant)
  previous_tenant = @current

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

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

  schema = first_schema(config[:schema_search_path]) if config[:schema_search_path]

  Innkeeper.connection.execute(%{DROP SCHEMA "#{schema}" CASCADE}) if schema

  @current = tenant
rescue ActiveRecord::StatementInvalid => exception
  raise TenantNotFound, "Error while dropping schema #{schema} for tenant #{tenant}: #{exception.message}"
ensure
  switch!(previous_tenant) rescue reset
end

#simple_switch(config) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
# File 'lib/innkeeper/adapters/postgresql_adapter.rb', line 52

def simple_switch(config)
  return unless config[:schema_search_path]

  tenant = first_schema(config[:schema_search_path])

  unless Innkeeper.connection.schema_exists?(tenant)
    raise Innkeeper::TenantNotFound, "Could not find schema #{tenant}"
  end

  Innkeeper.connection.schema_search_path = config[:schema_search_path]
end

#switch_tenant(config) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/innkeeper/adapters/postgresql_adapter.rb', line 40

def switch_tenant(config)
  current_config = config_for(@current)
  difference = config.select{ |k, v| current_config[k] != v }

  # PG doesn't have the ability to switch DB without reconnecting
  if difference[:host] || difference[:database]
    connection_switch!(config)
  else
    simple_switch(config) if difference[:schema_search_path]
  end
end