ros-apartment 2.3.0.alpha2 → 2.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/.rubocop-linter.yml +22 -0
  3. data/.pryrc +5 -3
  4. data/.rubocop.yml +21 -0
  5. data/.rubocop_todo.yml +29 -0
  6. data/.story_branch.yml +4 -0
  7. data/.travis.yml +15 -36
  8. data/Appraisals +16 -29
  9. data/Gemfile +4 -1
  10. data/Guardfile +3 -1
  11. data/HISTORY.md +7 -0
  12. data/README.md +80 -39
  13. data/Rakefile +45 -23
  14. data/apartment.gemspec +33 -25
  15. data/gemfiles/rails_4_2.gemfile +12 -10
  16. data/gemfiles/rails_5_0.gemfile +2 -1
  17. data/gemfiles/rails_5_1.gemfile +2 -1
  18. data/gemfiles/rails_5_2.gemfile +2 -1
  19. data/gemfiles/rails_6_0.gemfile +6 -5
  20. data/gemfiles/rails_master.gemfile +2 -1
  21. data/lib/apartment.rb +36 -11
  22. data/lib/apartment/active_record/connection_handling.rb +17 -0
  23. data/lib/apartment/active_record/internal_metadata.rb +11 -0
  24. data/lib/apartment/active_record/schema_migration.rb +13 -0
  25. data/lib/apartment/adapters/abstract_adapter.rb +50 -45
  26. data/lib/apartment/adapters/abstract_jdbc_adapter.rb +4 -3
  27. data/lib/apartment/adapters/jdbc_mysql_adapter.rb +3 -3
  28. data/lib/apartment/adapters/jdbc_postgresql_adapter.rb +20 -13
  29. data/lib/apartment/adapters/mysql2_adapter.rb +10 -9
  30. data/lib/apartment/adapters/postgis_adapter.rb +3 -2
  31. data/lib/apartment/adapters/postgresql_adapter.rb +55 -27
  32. data/lib/apartment/adapters/sqlite3_adapter.rb +18 -8
  33. data/lib/apartment/console.rb +35 -3
  34. data/lib/apartment/custom_console.rb +42 -0
  35. data/lib/apartment/deprecation.rb +2 -1
  36. data/lib/apartment/elevators/domain.rb +4 -3
  37. data/lib/apartment/elevators/first_subdomain.rb +3 -2
  38. data/lib/apartment/elevators/generic.rb +4 -3
  39. data/lib/apartment/elevators/host.rb +6 -1
  40. data/lib/apartment/elevators/host_hash.rb +6 -2
  41. data/lib/apartment/elevators/subdomain.rb +9 -5
  42. data/lib/apartment/migrator.rb +4 -3
  43. data/lib/apartment/model.rb +27 -0
  44. data/lib/apartment/railtie.rb +26 -15
  45. data/lib/apartment/reloader.rb +2 -1
  46. data/lib/apartment/tasks/enhancements.rb +4 -6
  47. data/lib/apartment/tenant.rb +19 -9
  48. data/lib/apartment/version.rb +3 -1
  49. data/lib/generators/apartment/install/install_generator.rb +4 -3
  50. data/lib/generators/apartment/install/templates/apartment.rb +3 -2
  51. data/lib/tasks/apartment.rake +24 -19
  52. metadata +79 -256
  53. data/spec/adapters/jdbc_mysql_adapter_spec.rb +0 -19
  54. data/spec/adapters/jdbc_postgresql_adapter_spec.rb +0 -41
  55. data/spec/adapters/mysql2_adapter_spec.rb +0 -59
  56. data/spec/adapters/postgresql_adapter_spec.rb +0 -61
  57. data/spec/adapters/sqlite3_adapter_spec.rb +0 -83
  58. data/spec/apartment_spec.rb +0 -11
  59. data/spec/config/database.yml.sample +0 -49
  60. data/spec/dummy/Rakefile +0 -7
  61. data/spec/dummy/app/controllers/application_controller.rb +0 -6
  62. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  63. data/spec/dummy/app/models/company.rb +0 -3
  64. data/spec/dummy/app/models/user.rb +0 -3
  65. data/spec/dummy/app/views/application/index.html.erb +0 -1
  66. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  67. data/spec/dummy/config.ru +0 -4
  68. data/spec/dummy/config/application.rb +0 -49
  69. data/spec/dummy/config/boot.rb +0 -11
  70. data/spec/dummy/config/database.yml.sample +0 -44
  71. data/spec/dummy/config/environment.rb +0 -5
  72. data/spec/dummy/config/environments/development.rb +0 -28
  73. data/spec/dummy/config/environments/production.rb +0 -51
  74. data/spec/dummy/config/environments/test.rb +0 -34
  75. data/spec/dummy/config/initializers/apartment.rb +0 -4
  76. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  77. data/spec/dummy/config/initializers/inflections.rb +0 -10
  78. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  79. data/spec/dummy/config/initializers/secret_token.rb +0 -7
  80. data/spec/dummy/config/initializers/session_store.rb +0 -8
  81. data/spec/dummy/config/locales/en.yml +0 -5
  82. data/spec/dummy/config/routes.rb +0 -3
  83. data/spec/dummy/db/migrate/20110613152810_create_dummy_models.rb +0 -39
  84. data/spec/dummy/db/migrate/20111202022214_create_table_books.rb +0 -14
  85. data/spec/dummy/db/migrate/20180415260934_create_public_tokens.rb +0 -13
  86. data/spec/dummy/db/schema.rb +0 -55
  87. data/spec/dummy/db/seeds.rb +0 -5
  88. data/spec/dummy/db/seeds/import.rb +0 -5
  89. data/spec/dummy/public/404.html +0 -26
  90. data/spec/dummy/public/422.html +0 -26
  91. data/spec/dummy/public/500.html +0 -26
  92. data/spec/dummy/public/favicon.ico +0 -0
  93. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  94. data/spec/dummy/script/rails +0 -6
  95. data/spec/dummy_engine/.gitignore +0 -8
  96. data/spec/dummy_engine/Gemfile +0 -15
  97. data/spec/dummy_engine/Rakefile +0 -34
  98. data/spec/dummy_engine/bin/rails +0 -12
  99. data/spec/dummy_engine/config/initializers/apartment.rb +0 -51
  100. data/spec/dummy_engine/dummy_engine.gemspec +0 -24
  101. data/spec/dummy_engine/lib/dummy_engine.rb +0 -4
  102. data/spec/dummy_engine/lib/dummy_engine/engine.rb +0 -4
  103. data/spec/dummy_engine/lib/dummy_engine/version.rb +0 -3
  104. data/spec/dummy_engine/test/dummy/Rakefile +0 -6
  105. data/spec/dummy_engine/test/dummy/config.ru +0 -4
  106. data/spec/dummy_engine/test/dummy/config/application.rb +0 -22
  107. data/spec/dummy_engine/test/dummy/config/boot.rb +0 -5
  108. data/spec/dummy_engine/test/dummy/config/database.yml +0 -25
  109. data/spec/dummy_engine/test/dummy/config/environment.rb +0 -5
  110. data/spec/dummy_engine/test/dummy/config/environments/development.rb +0 -37
  111. data/spec/dummy_engine/test/dummy/config/environments/production.rb +0 -78
  112. data/spec/dummy_engine/test/dummy/config/environments/test.rb +0 -39
  113. data/spec/dummy_engine/test/dummy/config/initializers/assets.rb +0 -8
  114. data/spec/dummy_engine/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  115. data/spec/dummy_engine/test/dummy/config/initializers/cookies_serializer.rb +0 -3
  116. data/spec/dummy_engine/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  117. data/spec/dummy_engine/test/dummy/config/initializers/inflections.rb +0 -16
  118. data/spec/dummy_engine/test/dummy/config/initializers/mime_types.rb +0 -4
  119. data/spec/dummy_engine/test/dummy/config/initializers/session_store.rb +0 -3
  120. data/spec/dummy_engine/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  121. data/spec/dummy_engine/test/dummy/config/locales/en.yml +0 -23
  122. data/spec/dummy_engine/test/dummy/config/routes.rb +0 -56
  123. data/spec/dummy_engine/test/dummy/config/secrets.yml +0 -22
  124. data/spec/examples/connection_adapter_examples.rb +0 -42
  125. data/spec/examples/generic_adapter_custom_configuration_example.rb +0 -95
  126. data/spec/examples/generic_adapter_examples.rb +0 -163
  127. data/spec/examples/schema_adapter_examples.rb +0 -234
  128. data/spec/integration/apartment_rake_integration_spec.rb +0 -107
  129. data/spec/integration/query_caching_spec.rb +0 -81
  130. data/spec/integration/use_within_an_engine_spec.rb +0 -28
  131. data/spec/schemas/v1.rb +0 -16
  132. data/spec/schemas/v2.rb +0 -43
  133. data/spec/schemas/v3.rb +0 -49
  134. data/spec/spec_helper.rb +0 -61
  135. data/spec/support/apartment_helpers.rb +0 -43
  136. data/spec/support/capybara_sessions.rb +0 -15
  137. data/spec/support/config.rb +0 -10
  138. data/spec/support/contexts.rb +0 -52
  139. data/spec/support/requirements.rb +0 -35
  140. data/spec/support/setup.rb +0 -46
  141. data/spec/tasks/apartment_rake_spec.rb +0 -129
  142. data/spec/tenant_spec.rb +0 -190
  143. data/spec/unit/config_spec.rb +0 -112
  144. data/spec/unit/elevators/domain_spec.rb +0 -32
  145. data/spec/unit/elevators/first_subdomain_spec.rb +0 -24
  146. data/spec/unit/elevators/generic_spec.rb +0 -54
  147. data/spec/unit/elevators/host_hash_spec.rb +0 -32
  148. data/spec/unit/elevators/host_spec.rb +0 -89
  149. data/spec/unit/elevators/subdomain_spec.rb +0 -76
  150. data/spec/unit/migrator_spec.rb +0 -77
  151. data/spec/unit/reloader_spec.rb +0 -24
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ module ConnectionHandling
5
+ def connected_to_with_tenant(database: nil, role: nil, prevent_writes: false, &blk)
6
+ current_tenant = Apartment::Tenant.current
7
+
8
+ connected_to_without_tenant(database: database, role: role, prevent_writes: prevent_writes) do
9
+ Apartment::Tenant.switch!(current_tenant)
10
+ yield(blk)
11
+ end
12
+ end
13
+
14
+ alias connected_to_without_tenant connected_to
15
+ alias connected_to connected_to_with_tenant
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Rails/ApplicationRecord
4
+ class InternalMetadata < ActiveRecord::Base # :nodoc:
5
+ class << self
6
+ def table_exists?
7
+ connection.table_exists?(table_name)
8
+ end
9
+ end
10
+ end
11
+ # rubocop:enable Rails/ApplicationRecord
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveRecord
4
+ # rubocop:disable Rails/ApplicationRecord
5
+ class SchemaMigration < ActiveRecord::Base # :nodoc:
6
+ class << self
7
+ def table_exists?
8
+ connection.table_exists?(table_name)
9
+ end
10
+ end
11
+ end
12
+ # rubocop:enable Rails/ApplicationRecord
13
+ end
@@ -1,5 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Apartment
2
4
  module Adapters
5
+ # rubocop:disable Metrics/ClassLength
3
6
  class AbstractAdapter
4
7
  include ActiveSupport::Callbacks
5
8
  define_callbacks :create, :switch
@@ -32,6 +35,12 @@ module Apartment
32
35
  end
33
36
  end
34
37
 
38
+ # Initialize Apartment config options such as excluded_models
39
+ #
40
+ def init
41
+ process_excluded_models
42
+ end
43
+
35
44
  # Note alias_method here doesn't work with inheritence apparently ??
36
45
  #
37
46
  def current
@@ -45,7 +54,7 @@ module Apartment
45
54
  def default_tenant
46
55
  @default_tenant || Apartment.default_tenant
47
56
  end
48
- alias :default_schema :default_tenant # TODO deprecate default_schema
57
+ alias default_schema default_tenant # TODO: deprecate default_schema
49
58
 
50
59
  # Drop the tenant
51
60
  #
@@ -55,9 +64,8 @@ module Apartment
55
64
  with_neutral_connection(tenant) do |conn|
56
65
  drop_command(conn, tenant)
57
66
  end
58
-
59
- rescue *rescuable_exceptions => exception
60
- raise_drop_tenant_error!(tenant, exception)
67
+ rescue *rescuable_exceptions => e
68
+ raise_drop_tenant_error!(tenant, e)
61
69
  end
62
70
 
63
71
  # Switch to a new tenant
@@ -66,8 +74,6 @@ module Apartment
66
74
  #
67
75
  def switch!(tenant = nil)
68
76
  run_callbacks :switch do
69
- return reset if tenant.nil?
70
-
71
77
  connect_to_new(tenant).tap do
72
78
  Apartment.connection.clear_query_cache
73
79
  end
@@ -79,13 +85,14 @@ module Apartment
79
85
  # @param {String?} tenant to connect to
80
86
  #
81
87
  def switch(tenant = nil)
88
+ previous_tenant = current
89
+ switch!(tenant)
90
+ yield
91
+ ensure
82
92
  begin
83
- previous_tenant = current
84
- switch!(tenant)
85
- yield
86
-
87
- ensure
88
- switch!(previous_tenant) rescue reset
93
+ switch!(previous_tenant)
94
+ rescue StandardError => _e
95
+ reset
89
96
  end
90
97
  end
91
98
 
@@ -93,14 +100,15 @@ module Apartment
93
100
  #
94
101
  def each(tenants = Apartment.tenant_names)
95
102
  tenants.each do |tenant|
96
- switch(tenant){ yield tenant }
103
+ switch(tenant) { yield tenant }
97
104
  end
98
105
  end
99
106
 
100
107
  # Establish a new connection for each specific excluded model
101
108
  #
102
109
  def process_excluded_models
103
- # All other models will shared a connection (at Apartment.connection_class) and we can modify at will
110
+ # All other models will shared a connection (at Apartment.connection_class)
111
+ # and we can modify at will
104
112
  Apartment.excluded_models.each do |excluded_model|
105
113
  process_excluded_model(excluded_model)
106
114
  end
@@ -116,9 +124,9 @@ module Apartment
116
124
  #
117
125
  def seed_data
118
126
  # Don't log the output of seeding the db
119
- silence_warnings{ load_or_raise(Apartment.seed_data_file) } if Apartment.seed_data_file
127
+ silence_warnings { load_or_raise(Apartment.seed_data_file) } if Apartment.seed_data_file
120
128
  end
121
- alias_method :seed, :seed_data
129
+ alias seed seed_data
122
130
 
123
131
  # Prepend the environment if configured and the environment isn't already there
124
132
  #
@@ -126,20 +134,18 @@ module Apartment
126
134
  # @return {String} tenant name with Rails environment *optionally* prepended
127
135
  #
128
136
  def environmentify(tenant)
129
- unless tenant.include?(Rails.env)
130
- if Apartment.prepend_environment
131
- "#{Rails.env}_#{tenant}"
132
- elsif Apartment.append_environment
133
- "#{tenant}_#{Rails.env}"
134
- else
135
- tenant
136
- end
137
+ return tenant if tenant.nil? || tenant.include?(Rails.env)
138
+
139
+ if Apartment.prepend_environment
140
+ "#{Rails.env}_#{tenant}"
141
+ elsif Apartment.append_environment
142
+ "#{tenant}_#{Rails.env}"
137
143
  else
138
144
  tenant
139
145
  end
140
146
  end
141
147
 
142
- protected
148
+ protected
143
149
 
144
150
  def process_excluded_model(excluded_model)
145
151
  excluded_model.constantize.establish_connection @config
@@ -158,8 +164,8 @@ module Apartment
158
164
  with_neutral_connection(tenant) do |conn|
159
165
  create_tenant_command(conn, tenant)
160
166
  end
161
- rescue *rescuable_exceptions => exception
162
- raise_create_tenant_error!(tenant, exception)
167
+ rescue *rescuable_exceptions => e
168
+ raise_create_tenant_error!(tenant, e)
163
169
  end
164
170
 
165
171
  def create_tenant_command(conn, tenant)
@@ -171,21 +177,23 @@ module Apartment
171
177
  # @param {String} tenant Database name
172
178
  #
173
179
  def connect_to_new(tenant)
180
+ return reset if tenant.nil?
181
+
174
182
  query_cache_enabled = ActiveRecord::Base.connection.query_cache_enabled
175
183
 
176
184
  Apartment.establish_connection multi_tenantify(tenant)
177
- Apartment.connection.active? # call active? to manually check if this connection is valid
185
+ Apartment.connection.active? # call active? to manually check if this connection is valid
178
186
 
179
187
  Apartment.connection.enable_query_cache! if query_cache_enabled
180
- rescue *rescuable_exceptions => exception
188
+ rescue *rescuable_exceptions => e
181
189
  Apartment::Tenant.reset if reset_on_connection_exception?
182
- raise_connect_error!(tenant, exception)
190
+ raise_connect_error!(tenant, e)
183
191
  end
184
192
 
185
193
  # Import the database schema
186
194
  #
187
195
  def import_database_schema
188
- ActiveRecord::Schema.verbose = false # do not log schema load output.
196
+ ActiveRecord::Schema.verbose = false # do not log schema load output.
189
197
 
190
198
  load_or_raise(Apartment.database_schema_file) if Apartment.database_schema_file
191
199
  end
@@ -196,9 +204,7 @@ module Apartment
196
204
  # if false, use the default db name from the db
197
205
  def multi_tenantify(tenant, with_database = true)
198
206
  db_connection_config(tenant).tap do |config|
199
- if with_database
200
- multi_tenantify_with_tenant_db_name(config, tenant)
201
- end
207
+ multi_tenantify_with_tenant_db_name(config, tenant) if with_database
202
208
  end
203
209
  end
204
210
 
@@ -209,14 +215,12 @@ module Apartment
209
215
  # Load a file or raise error if it doesn't exists
210
216
  #
211
217
  def load_or_raise(file)
212
- if File.exists?(file)
213
- load(file)
214
- else
215
- raise FileNotFound, "#{file} doesn't exist yet"
216
- end
218
+ raise FileNotFound, "#{file} doesn't exist yet" unless File.exist?(file)
219
+
220
+ load(file)
217
221
  end
218
222
  # Backward compatibility
219
- alias_method :load_or_abort, :load_or_raise
223
+ alias load_or_abort load_or_raise
220
224
 
221
225
  # Exceptions to rescue from on db operations
222
226
  #
@@ -231,10 +235,10 @@ module Apartment
231
235
  end
232
236
 
233
237
  def db_connection_config(tenant)
234
- Apartment.db_config_for(tenant).clone
238
+ Apartment.db_config_for(tenant).dup
235
239
  end
236
240
 
237
- def with_neutral_connection(tenant, &block)
241
+ def with_neutral_connection(tenant, &_block)
238
242
  if Apartment.with_multi_server_setup
239
243
  # neutral connection is necessary whenever you need to create/remove a database from a server.
240
244
  # example: when you use postgresql, you need to connect to the default postgresql database before you create your own.
@@ -251,19 +255,20 @@ module Apartment
251
255
  end
252
256
 
253
257
  def raise_drop_tenant_error!(tenant, exception)
254
- raise TenantNotFound, "Error while dropping tenant #{environmentify(tenant)}: #{ exception.message }"
258
+ raise TenantNotFound, "Error while dropping tenant #{environmentify(tenant)}: #{exception.message}"
255
259
  end
256
260
 
257
261
  def raise_create_tenant_error!(tenant, exception)
258
- raise TenantExists, "Error while creating tenant #{environmentify(tenant)}: #{ exception.message }"
262
+ raise TenantExists, "Error while creating tenant #{environmentify(tenant)}: #{exception.message}"
259
263
  end
260
264
 
261
265
  def raise_connect_error!(tenant, exception)
262
- raise TenantNotFound, "Error while connecting to tenant #{environmentify(tenant)}: #{ exception.message }"
266
+ raise TenantNotFound, "Error while connecting to tenant #{environmentify(tenant)}: #{exception.message}"
263
267
  end
264
268
 
265
269
  class SeparateDbConnectionHandler < ::ActiveRecord::Base
266
270
  end
267
271
  end
268
272
  end
273
+ # rubocop:enable Metrics/ClassLength
269
274
  end
@@ -1,13 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'apartment/adapters/abstract_adapter'
2
4
 
3
5
  module Apartment
4
6
  module Adapters
5
7
  class AbstractJDBCAdapter < AbstractAdapter
6
-
7
- private
8
+ private
8
9
 
9
10
  def multi_tenantify_with_tenant_db_name(config, tenant)
10
- config[:url] = "#{config[:url].gsub(/(\S+)\/.+$/, '\1')}/#{environmentify(tenant)}"
11
+ config[:url] = "#{config[:url].gsub(%r{(\S+)\/.+$}, '\1')}/#{environmentify(tenant)}"
11
12
  end
12
13
 
13
14
  def rescue_from
@@ -1,7 +1,8 @@
1
- require "apartment/adapters/abstract_jdbc_adapter"
1
+ # frozen_string_literal: true
2
2
 
3
- module Apartment
3
+ require 'apartment/adapters/abstract_jdbc_adapter'
4
4
 
5
+ module Apartment
5
6
  module Tenant
6
7
  def self.jdbc_mysql_adapter(config)
7
8
  Adapters::JDBCMysqlAdapter.new config
@@ -10,7 +11,6 @@ module Apartment
10
11
 
11
12
  module Adapters
12
13
  class JDBCMysqlAdapter < AbstractJDBCAdapter
13
-
14
14
  def reset_on_connection_exception?
15
15
  true
16
16
  end
@@ -1,28 +1,29 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'apartment/adapters/postgresql_adapter'
2
4
 
3
5
  module Apartment
4
6
  module Tenant
5
-
6
7
  def self.jdbc_postgresql_adapter(config)
7
- Apartment.use_schemas ?
8
- Adapters::JDBCPostgresqlSchemaAdapter.new(config) :
8
+ if Apartment.use_schemas
9
+ Adapters::JDBCPostgresqlSchemaAdapter.new(config)
10
+ else
9
11
  Adapters::JDBCPostgresqlAdapter.new(config)
12
+ end
10
13
  end
11
14
  end
12
15
 
13
16
  module Adapters
14
-
15
17
  # Default adapter when not using Postgresql Schemas
16
18
  class JDBCPostgresqlAdapter < PostgresqlAdapter
17
-
18
- private
19
+ private
19
20
 
20
21
  def multi_tenantify_with_tenant_db_name(config, tenant)
21
- config[:url] = "#{config[:url].gsub(/(\S+)\/.+$/, '\1')}/#{environmentify(tenant)}"
22
+ config[:url] = "#{config[:url].gsub(%r{(\S+)\/.+$}, '\1')}/#{environmentify(tenant)}"
22
23
  end
23
24
 
24
25
  def create_tenant_command(conn, tenant)
25
- conn.create_database(environmentify(tenant), { :thisisahack => '' })
26
+ conn.create_database(environmentify(tenant), thisisahack: '')
26
27
  end
27
28
 
28
29
  def rescue_from
@@ -32,21 +33,27 @@ module Apartment
32
33
 
33
34
  # Separate Adapter for Postgresql when using schemas
34
35
  class JDBCPostgresqlSchemaAdapter < PostgresqlSchemaAdapter
35
-
36
36
  # Set schema search path to new schema
37
37
  #
38
38
  def connect_to_new(tenant = nil)
39
39
  return reset if tenant.nil?
40
- raise ActiveRecord::StatementInvalid.new("Could not find schema #{tenant}") unless Apartment.connection.all_schemas.include? tenant.to_s
41
40
 
42
- @current = tenant.to_s
43
- Apartment.connection.schema_search_path = full_search_path
41
+ tenant = tenant.to_s
42
+ raise ActiveRecord::StatementInvalid, "Could not find schema #{tenant}" unless tenant_exists?(tenant)
44
43
 
44
+ @current = tenant
45
+ Apartment.connection.schema_search_path = full_search_path
45
46
  rescue ActiveRecord::StatementInvalid, ActiveRecord::JDBCError
46
47
  raise TenantNotFound, "One of the following schema(s) is invalid: #{full_search_path}"
47
48
  end
48
49
 
49
- private
50
+ private
51
+
52
+ def tenant_exists?(tenant)
53
+ return true unless Apartment.tenant_presence_check
54
+
55
+ Apartment.connection.all_schemas.include? tenant
56
+ end
50
57
 
51
58
  def rescue_from
52
59
  ActiveRecord::JDBCError
@@ -1,25 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'apartment/adapters/abstract_adapter'
2
4
 
3
5
  module Apartment
4
6
  module Tenant
5
-
6
7
  def self.mysql2_adapter(config)
7
- Apartment.use_schemas ?
8
- Adapters::Mysql2SchemaAdapter.new(config) :
8
+ if Apartment.use_schemas
9
+ Adapters::Mysql2SchemaAdapter.new(config)
10
+ else
9
11
  Adapters::Mysql2Adapter.new(config)
12
+ end
10
13
  end
11
14
  end
12
15
 
13
16
  module Adapters
14
17
  class Mysql2Adapter < AbstractAdapter
15
-
16
18
  def initialize(config)
17
19
  super
18
20
 
19
21
  @default_tenant = config[:database]
20
22
  end
21
23
 
22
- protected
24
+ protected
23
25
 
24
26
  def rescue_from
25
27
  Mysql2::Error
@@ -40,7 +42,7 @@ module Apartment
40
42
  Apartment.connection.execute "use `#{default_tenant}`"
41
43
  end
42
44
 
43
- protected
45
+ protected
44
46
 
45
47
  # Connect to new tenant
46
48
  #
@@ -48,10 +50,9 @@ module Apartment
48
50
  return reset if tenant.nil?
49
51
 
50
52
  Apartment.connection.execute "use `#{environmentify(tenant)}`"
51
-
52
- rescue ActiveRecord::StatementInvalid => exception
53
+ rescue ActiveRecord::StatementInvalid => e
53
54
  Apartment::Tenant.reset
54
- raise_connect_error!(tenant, exception)
55
+ raise_connect_error!(tenant, e)
55
56
  end
56
57
 
57
58
  def process_excluded_model(model)
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # handle postgis adapter as if it were postgresql,
2
4
  # only override the adapter_method used for initialization
3
- require "apartment/adapters/postgresql_adapter"
5
+ require 'apartment/adapters/postgresql_adapter'
4
6
 
5
7
  module Apartment
6
8
  module Tenant
7
-
8
9
  def self.postgis_adapter(config)
9
10
  postgresql_adapter(config)
10
11
  end