-
Notifications
You must be signed in to change notification settings - Fork 460
Expand file tree
/
Copy pathapartment.rb
More file actions
126 lines (96 loc) · 3.49 KB
/
apartment.rb
File metadata and controls
126 lines (96 loc) · 3.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
require 'apartment/railtie' if defined?(Rails)
require 'active_support/core_ext/object/blank'
require 'forwardable'
require 'active_record'
require 'apartment/tenant'
module Apartment
class << self
extend Forwardable
ACCESSOR_METHODS = [:use_schemas, :use_sql, :seed_after_create, :prepend_environment, :append_environment, :with_multi_server_setup]
WRITER_METHODS = [:tenant_names, :database_schema_file, :excluded_models, :default_schema, :persistent_schemas, :connection_class, :tld_length, :db_migrate_tenants, :seed_data_file, :parallel_migration_threads, :pg_excluded_names]
attr_accessor(*ACCESSOR_METHODS)
attr_writer(*WRITER_METHODS)
def_delegators :connection_class, :connection, :establish_connection
def connection_config
if ::ActiveRecord::Base.respond_to?(:connection_db_config)
::ActiveRecord::Base.connection_db_config.configuration_hash
else
::ActiveRecord::Base.connection_config
end
end
# configure apartment with available options
def configure
yield self if block_given?
end
def tenant_names
extract_tenant_config.keys.map(&:to_s)
end
def tenants_with_config
extract_tenant_config
end
def db_config_for(tenant)
(tenants_with_config[tenant] || connection_config).with_indifferent_access
end
# Whether or not db:migrate should also migrate tenants
# defaults to true
def db_migrate_tenants
return @db_migrate_tenants if defined?(@db_migrate_tenants)
@db_migrate_tenants = true
end
# Default to empty array
def excluded_models
@excluded_models || []
end
def default_schema
@default_schema || "public" # TODO 'public' is postgres specific
end
def parallel_migration_threads
@parallel_migration_threads || 0
end
alias :default_tenant :default_schema
alias :default_tenant= :default_schema=
def persistent_schemas
@persistent_schemas || []
end
def connection_class
@connection_class || ActiveRecord::Base
end
def database_schema_file
return @database_schema_file if defined?(@database_schema_file)
@database_schema_file = Rails.root.join('db', 'schema.rb')
end
def seed_data_file
return @seed_data_file if defined?(@seed_data_file)
@seed_data_file = "#{Rails.root}/db/seeds.rb"
end
def pg_excluded_names
@pg_excluded_names || []
end
# Reset all the config for Apartment
def reset
(ACCESSOR_METHODS + WRITER_METHODS).each{|method| remove_instance_variable(:"@#{method}") if instance_variable_defined?(:"@#{method}") }
end
def extract_tenant_config
return {} unless @tenant_names
values = @tenant_names.respond_to?(:call) ? @tenant_names.call : @tenant_names
unless values.is_a? Hash
values = values.each_with_object({}) do |tenant, hash|
hash[tenant] = connection_config
end
end
values.with_indifferent_access
rescue ActiveRecord::StatementInvalid
{}
end
end
# Exceptions
ApartmentError = Class.new(StandardError)
# Raised when apartment cannot find the adapter specified in <tt>config/database.yml</tt>
AdapterNotFound = Class.new(ApartmentError)
# Raised when apartment cannot find the file to be loaded
FileNotFound = Class.new(ApartmentError)
# Tenant specified is unknown
TenantNotFound = Class.new(ApartmentError)
# The Tenant attempting to be created already exists
TenantExists = Class.new(ApartmentError)
end