ros-apartment 2.3.0 → 2.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/.pryrc +5 -3
  3. data/.rubocop.yml +22 -0
  4. data/.rubocop_todo.yml +29 -0
  5. data/.story_branch.yml +5 -0
  6. data/.travis.yml +20 -36
  7. data/Appraisals +16 -29
  8. data/Gemfile +5 -2
  9. data/Guardfile +3 -1
  10. data/HISTORY.md +57 -0
  11. data/README.md +64 -21
  12. data/Rakefile +36 -22
  13. data/TODO.md +0 -1
  14. data/apartment.gemspec +17 -10
  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 +38 -14
  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/log_subscriber.rb +41 -0
  25. data/lib/apartment/active_record/schema_migration.rb +13 -0
  26. data/lib/apartment/adapters/abstract_adapter.rb +49 -45
  27. data/lib/apartment/adapters/abstract_jdbc_adapter.rb +4 -3
  28. data/lib/apartment/adapters/jdbc_mysql_adapter.rb +3 -3
  29. data/lib/apartment/adapters/jdbc_postgresql_adapter.rb +20 -13
  30. data/lib/apartment/adapters/mysql2_adapter.rb +12 -9
  31. data/lib/apartment/adapters/postgis_adapter.rb +3 -2
  32. data/lib/apartment/adapters/postgresql_adapter.rb +59 -27
  33. data/lib/apartment/adapters/sqlite3_adapter.rb +18 -8
  34. data/lib/apartment/console.rb +35 -3
  35. data/lib/apartment/custom_console.rb +42 -0
  36. data/lib/apartment/deprecation.rb +2 -1
  37. data/lib/apartment/elevators/domain.rb +4 -3
  38. data/lib/apartment/elevators/first_subdomain.rb +3 -2
  39. data/lib/apartment/elevators/generic.rb +4 -3
  40. data/lib/apartment/elevators/host.rb +6 -1
  41. data/lib/apartment/elevators/host_hash.rb +6 -2
  42. data/lib/apartment/elevators/subdomain.rb +9 -5
  43. data/lib/apartment/migrator.rb +4 -3
  44. data/lib/apartment/model.rb +27 -0
  45. data/lib/apartment/railtie.rb +27 -15
  46. data/lib/apartment/reloader.rb +2 -1
  47. data/lib/apartment/tasks/enhancements.rb +4 -6
  48. data/lib/apartment/tasks/task_helper.rb +35 -0
  49. data/lib/apartment/tenant.rb +19 -9
  50. data/lib/apartment/version.rb +3 -1
  51. data/lib/generators/apartment/install/install_generator.rb +4 -3
  52. data/lib/generators/apartment/install/templates/apartment.rb +8 -2
  53. data/lib/tasks/apartment.rake +22 -44
  54. metadata +51 -230
  55. data/spec/adapters/jdbc_mysql_adapter_spec.rb +0 -19
  56. data/spec/adapters/jdbc_postgresql_adapter_spec.rb +0 -41
  57. data/spec/adapters/mysql2_adapter_spec.rb +0 -59
  58. data/spec/adapters/postgresql_adapter_spec.rb +0 -61
  59. data/spec/adapters/sqlite3_adapter_spec.rb +0 -83
  60. data/spec/apartment_spec.rb +0 -11
  61. data/spec/config/database.yml.sample +0 -49
  62. data/spec/dummy/Rakefile +0 -7
  63. data/spec/dummy/app/controllers/application_controller.rb +0 -6
  64. data/spec/dummy/app/helpers/application_helper.rb +0 -2
  65. data/spec/dummy/app/models/company.rb +0 -3
  66. data/spec/dummy/app/models/user.rb +0 -3
  67. data/spec/dummy/app/views/application/index.html.erb +0 -1
  68. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  69. data/spec/dummy/config.ru +0 -4
  70. data/spec/dummy/config/application.rb +0 -49
  71. data/spec/dummy/config/boot.rb +0 -11
  72. data/spec/dummy/config/database.yml.sample +0 -44
  73. data/spec/dummy/config/environment.rb +0 -5
  74. data/spec/dummy/config/environments/development.rb +0 -28
  75. data/spec/dummy/config/environments/production.rb +0 -51
  76. data/spec/dummy/config/environments/test.rb +0 -34
  77. data/spec/dummy/config/initializers/apartment.rb +0 -4
  78. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  79. data/spec/dummy/config/initializers/inflections.rb +0 -10
  80. data/spec/dummy/config/initializers/mime_types.rb +0 -5
  81. data/spec/dummy/config/initializers/secret_token.rb +0 -7
  82. data/spec/dummy/config/initializers/session_store.rb +0 -8
  83. data/spec/dummy/config/locales/en.yml +0 -5
  84. data/spec/dummy/config/routes.rb +0 -3
  85. data/spec/dummy/db/migrate/20110613152810_create_dummy_models.rb +0 -39
  86. data/spec/dummy/db/migrate/20111202022214_create_table_books.rb +0 -14
  87. data/spec/dummy/db/migrate/20180415260934_create_public_tokens.rb +0 -13
  88. data/spec/dummy/db/schema.rb +0 -55
  89. data/spec/dummy/db/seeds.rb +0 -5
  90. data/spec/dummy/db/seeds/import.rb +0 -5
  91. data/spec/dummy/public/404.html +0 -26
  92. data/spec/dummy/public/422.html +0 -26
  93. data/spec/dummy/public/500.html +0 -26
  94. data/spec/dummy/public/favicon.ico +0 -0
  95. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  96. data/spec/dummy/script/rails +0 -6
  97. data/spec/dummy_engine/.gitignore +0 -8
  98. data/spec/dummy_engine/Gemfile +0 -15
  99. data/spec/dummy_engine/Rakefile +0 -34
  100. data/spec/dummy_engine/bin/rails +0 -12
  101. data/spec/dummy_engine/config/initializers/apartment.rb +0 -51
  102. data/spec/dummy_engine/dummy_engine.gemspec +0 -24
  103. data/spec/dummy_engine/lib/dummy_engine.rb +0 -4
  104. data/spec/dummy_engine/lib/dummy_engine/engine.rb +0 -4
  105. data/spec/dummy_engine/lib/dummy_engine/version.rb +0 -3
  106. data/spec/dummy_engine/test/dummy/Rakefile +0 -6
  107. data/spec/dummy_engine/test/dummy/config.ru +0 -4
  108. data/spec/dummy_engine/test/dummy/config/application.rb +0 -22
  109. data/spec/dummy_engine/test/dummy/config/boot.rb +0 -5
  110. data/spec/dummy_engine/test/dummy/config/database.yml +0 -25
  111. data/spec/dummy_engine/test/dummy/config/environment.rb +0 -5
  112. data/spec/dummy_engine/test/dummy/config/environments/development.rb +0 -37
  113. data/spec/dummy_engine/test/dummy/config/environments/production.rb +0 -78
  114. data/spec/dummy_engine/test/dummy/config/environments/test.rb +0 -39
  115. data/spec/dummy_engine/test/dummy/config/initializers/assets.rb +0 -8
  116. data/spec/dummy_engine/test/dummy/config/initializers/backtrace_silencers.rb +0 -7
  117. data/spec/dummy_engine/test/dummy/config/initializers/cookies_serializer.rb +0 -3
  118. data/spec/dummy_engine/test/dummy/config/initializers/filter_parameter_logging.rb +0 -4
  119. data/spec/dummy_engine/test/dummy/config/initializers/inflections.rb +0 -16
  120. data/spec/dummy_engine/test/dummy/config/initializers/mime_types.rb +0 -4
  121. data/spec/dummy_engine/test/dummy/config/initializers/session_store.rb +0 -3
  122. data/spec/dummy_engine/test/dummy/config/initializers/wrap_parameters.rb +0 -14
  123. data/spec/dummy_engine/test/dummy/config/locales/en.yml +0 -23
  124. data/spec/dummy_engine/test/dummy/config/routes.rb +0 -56
  125. data/spec/dummy_engine/test/dummy/config/secrets.yml +0 -22
  126. data/spec/examples/connection_adapter_examples.rb +0 -42
  127. data/spec/examples/generic_adapter_custom_configuration_example.rb +0 -95
  128. data/spec/examples/generic_adapter_examples.rb +0 -163
  129. data/spec/examples/schema_adapter_examples.rb +0 -234
  130. data/spec/integration/apartment_rake_integration_spec.rb +0 -107
  131. data/spec/integration/query_caching_spec.rb +0 -81
  132. data/spec/integration/use_within_an_engine_spec.rb +0 -28
  133. data/spec/schemas/v1.rb +0 -16
  134. data/spec/schemas/v2.rb +0 -43
  135. data/spec/schemas/v3.rb +0 -49
  136. data/spec/spec_helper.rb +0 -61
  137. data/spec/support/apartment_helpers.rb +0 -43
  138. data/spec/support/capybara_sessions.rb +0 -15
  139. data/spec/support/config.rb +0 -10
  140. data/spec/support/contexts.rb +0 -52
  141. data/spec/support/requirements.rb +0 -35
  142. data/spec/support/setup.rb +0 -46
  143. data/spec/tasks/apartment_rake_spec.rb +0 -129
  144. data/spec/tenant_spec.rb +0 -190
  145. data/spec/unit/config_spec.rb +0 -112
  146. data/spec/unit/elevators/domain_spec.rb +0 -32
  147. data/spec/unit/elevators/first_subdomain_spec.rb +0 -24
  148. data/spec/unit/elevators/generic_spec.rb +0 -54
  149. data/spec/unit/elevators/host_hash_spec.rb +0 -32
  150. data/spec/unit/elevators/host_spec.rb +0 -89
  151. data/spec/unit/elevators/subdomain_spec.rb +0 -76
  152. data/spec/unit/migrator_spec.rb +0 -77
  153. data/spec/unit/reloader_spec.rb +0 -24
@@ -1,23 +0,0 @@
1
- # Files in the config/locales directory are used for internationalization
2
- # and are automatically loaded by Rails. If you want to use locales other
3
- # than English, add the necessary files in this directory.
4
- #
5
- # To use the locales, use `I18n.t`:
6
- #
7
- # I18n.t 'hello'
8
- #
9
- # In views, this is aliased to just `t`:
10
- #
11
- # <%= t('hello') %>
12
- #
13
- # To use a different locale, set it with `I18n.locale`:
14
- #
15
- # I18n.locale = :es
16
- #
17
- # This would use the information in config/locales/es.yml.
18
- #
19
- # To learn more, please read the Rails Internationalization guide
20
- # available at http://guides.rubyonrails.org/i18n.html.
21
-
22
- en:
23
- hello: "Hello world"
@@ -1,56 +0,0 @@
1
- Rails.application.routes.draw do
2
- # The priority is based upon order of creation: first created -> highest priority.
3
- # See how all your routes lay out with "rake routes".
4
-
5
- # You can have the root of your site routed with "root"
6
- # root 'welcome#index'
7
-
8
- # Example of regular route:
9
- # get 'products/:id' => 'catalog#view'
10
-
11
- # Example of named route that can be invoked with purchase_url(id: product.id)
12
- # get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
13
-
14
- # Example resource route (maps HTTP verbs to controller actions automatically):
15
- # resources :products
16
-
17
- # Example resource route with options:
18
- # resources :products do
19
- # member do
20
- # get 'short'
21
- # post 'toggle'
22
- # end
23
- #
24
- # collection do
25
- # get 'sold'
26
- # end
27
- # end
28
-
29
- # Example resource route with sub-resources:
30
- # resources :products do
31
- # resources :comments, :sales
32
- # resource :seller
33
- # end
34
-
35
- # Example resource route with more complex sub-resources:
36
- # resources :products do
37
- # resources :comments
38
- # resources :sales do
39
- # get 'recent', on: :collection
40
- # end
41
- # end
42
-
43
- # Example resource route with concerns:
44
- # concern :toggleable do
45
- # post 'toggle'
46
- # end
47
- # resources :posts, concerns: :toggleable
48
- # resources :photos, concerns: :toggleable
49
-
50
- # Example resource route within a namespace:
51
- # namespace :admin do
52
- # # Directs /admin/products/* to Admin::ProductsController
53
- # # (app/controllers/admin/products_controller.rb)
54
- # resources :products
55
- # end
56
- end
@@ -1,22 +0,0 @@
1
- # Be sure to restart your server when you modify this file.
2
-
3
- # Your secret key is used for verifying the integrity of signed cookies.
4
- # If you change this key, all old signed cookies will become invalid!
5
-
6
- # Make sure the secret is at least 30 characters and all random,
7
- # no regular words or you'll be exposed to dictionary attacks.
8
- # You can use `rake secret` to generate a secure secret key.
9
-
10
- # Make sure the secrets in this file are kept private
11
- # if you're sharing your code publicly.
12
-
13
- development:
14
- secret_key_base: bb62b819b585a74e69c797f9d03d5a004d8fe82a8e7a7da6fa2f7923030713b7b087c12cc7a918e71073c38afb343f7223d22ba3f1b223b7e76dbf8d5b65fa2c
15
-
16
- test:
17
- secret_key_base: 67945d3b189c71dffef98de2bb7c14d6fb059679c115ca3cddf65c88babe130afe4d583560d0e308b017dd76ce305bef4159d876de9fd893952d9cbf269c8476
18
-
19
- # Do not keep production secrets in the repository,
20
- # instead read values from the environment.
21
- production:
22
- secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- shared_examples_for "a connection based apartment adapter" do
4
- include Apartment::Spec::AdapterRequirements
5
-
6
- let(:default_tenant){ subject.switch{ ActiveRecord::Base.connection.current_database } }
7
-
8
- describe "#init" do
9
- after do
10
- # Apartment::Tenant.init creates per model connection.
11
- # Remove the connection after testing not to unintentionally keep the connection across tests.
12
- Apartment.excluded_models.each do |excluded_model|
13
- excluded_model.constantize.remove_connection
14
- end
15
- end
16
-
17
- it "should process model exclusions" do
18
- Apartment.configure do |config|
19
- config.excluded_models = ["Company"]
20
- end
21
- Apartment::Tenant.init
22
-
23
- expect(Company.connection.object_id).not_to eq(ActiveRecord::Base.connection.object_id)
24
- end
25
- end
26
-
27
- describe "#drop" do
28
- it "should raise an error for unknown database" do
29
- expect {
30
- subject.drop 'unknown_database'
31
- }.to raise_error(Apartment::TenantNotFound)
32
- end
33
- end
34
-
35
- describe "#switch!" do
36
- it "should raise an error if database is invalid" do
37
- expect {
38
- subject.switch! 'unknown_database'
39
- }.to raise_error(Apartment::TenantNotFound)
40
- end
41
- end
42
- end
@@ -1,95 +0,0 @@
1
- require 'spec_helper'
2
-
3
- shared_examples_for "a generic apartment adapter able to handle custom configuration" do
4
-
5
- let(:custom_tenant_name) { 'test_tenantwwww' }
6
- let(:db) { |example| example.metadata[:database]}
7
- let(:custom_tenant_names) do
8
- {
9
- custom_tenant_name => get_custom_db_conf
10
- }
11
- end
12
-
13
- before do
14
- Apartment.tenant_names = custom_tenant_names
15
- Apartment.with_multi_server_setup = true
16
- end
17
-
18
- after do
19
- Apartment.with_multi_server_setup = false
20
- end
21
-
22
- context "database key taken from specific config" do
23
-
24
- let(:expected_args) { get_custom_db_conf }
25
-
26
- describe "#create" do
27
- it "should establish_connection with the separate connection with expected args" do
28
- expect(Apartment::Adapters::AbstractAdapter::SeparateDbConnectionHandler).to receive(:establish_connection).with(expected_args).and_call_original
29
-
30
- # because we dont have another server to connect to it errors
31
- # what matters is establish_connection receives proper args
32
- expect { subject.create(custom_tenant_name) }.to raise_error(Apartment::TenantExists)
33
- end
34
- end
35
-
36
- describe "#drop" do
37
- it "should establish_connection with the separate connection with expected args" do
38
- expect(Apartment::Adapters::AbstractAdapter::SeparateDbConnectionHandler).to receive(:establish_connection).with(expected_args).and_call_original
39
-
40
- # because we dont have another server to connect to it errors
41
- # what matters is establish_connection receives proper args
42
- expect { subject.drop(custom_tenant_name) }.to raise_error(Apartment::TenantNotFound)
43
- end
44
- end
45
- end
46
-
47
- context "database key from tenant name" do
48
-
49
- let(:expected_args) {
50
- get_custom_db_conf.tap {|args| args.delete(:database) }
51
- }
52
-
53
- describe "#switch!" do
54
-
55
- it "should connect to new db" do
56
- expect(Apartment).to receive(:establish_connection) do |args|
57
- db_name = args.delete(:database)
58
-
59
- expect(args).to eq expected_args
60
- expect(db_name).to match custom_tenant_name
61
-
62
- # we only need to check args, then we short circuit
63
- # in order to avoid the mess due to the `establish_connection` override
64
- raise ActiveRecord::ActiveRecordError
65
- end
66
-
67
- expect { subject.switch!(custom_tenant_name) }.to raise_error(Apartment::TenantNotFound)
68
- end
69
- end
70
- end
71
-
72
- def specific_connection
73
- {
74
- postgresql: {
75
- adapter: 'postgresql',
76
- database: 'override_database',
77
- password: 'override_password',
78
- username: 'overridepostgres'
79
- },
80
- mysql: {
81
- adapter: 'mysql2',
82
- database: 'override_database',
83
- username: 'root'
84
- },
85
- sqlite: {
86
- adapter: 'sqlite3',
87
- database: 'override_database'
88
- }
89
- }
90
- end
91
-
92
- def get_custom_db_conf
93
- specific_connection[db.to_sym].with_indifferent_access
94
- end
95
- end
@@ -1,163 +0,0 @@
1
- require 'spec_helper'
2
-
3
- shared_examples_for "a generic apartment adapter" do
4
- include Apartment::Spec::AdapterRequirements
5
-
6
- before {
7
- Apartment.prepend_environment = false
8
- Apartment.append_environment = false
9
- }
10
-
11
- describe "#init" do
12
- it "should not retain a connection after railtie" do
13
- # this test should work on rails >= 4, the connection pool code is
14
- # completely different for 3.2 so we'd have to have a messy conditional..
15
- unless Rails::VERSION::MAJOR < 4
16
- ActiveRecord::Base.connection_pool.disconnect!
17
-
18
- Apartment::Railtie.config.to_prepare_blocks.map(&:call)
19
-
20
- num_available_connections = Apartment.connection_class.connection_pool
21
- .instance_variable_get(:@available)
22
- .instance_variable_get(:@queue)
23
- .size
24
-
25
- expect(num_available_connections).to eq(1)
26
- end
27
- end
28
- end
29
-
30
- #
31
- # Creates happen already in our before_filter
32
- #
33
- describe "#create" do
34
-
35
- it "should create the new databases" do
36
- expect(tenant_names).to include(db1)
37
- expect(tenant_names).to include(db2)
38
- end
39
-
40
- it "should load schema.rb to new schema" do
41
- subject.switch(db1) do
42
- expect(connection.tables).to include('companies')
43
- end
44
- end
45
-
46
- it "should yield to block if passed and reset" do
47
- subject.drop(db2) # so we don't get errors on creation
48
-
49
- @count = 0 # set our variable so its visible in and outside of blocks
50
-
51
- subject.create(db2) do
52
- @count = User.count
53
- expect(subject.current).to eq(db2)
54
- User.create
55
- end
56
-
57
- expect(subject.current).not_to eq(db2)
58
-
59
- subject.switch(db2){ expect(User.count).to eq(@count + 1) }
60
- end
61
-
62
- it "should raise error when the schema.rb is missing unless Apartment.use_sql is set to true" do
63
- next if Apartment.use_sql
64
-
65
- subject.drop(db1)
66
- begin
67
- Dir.mktmpdir do |tmpdir|
68
- Apartment.database_schema_file = "#{tmpdir}/schema.rb"
69
- expect {
70
- subject.create(db1)
71
- }.to raise_error(Apartment::FileNotFound)
72
- end
73
- ensure
74
- Apartment.remove_instance_variable(:@database_schema_file)
75
- end
76
- end
77
- end
78
-
79
- describe "#drop" do
80
- it "should remove the db" do
81
- subject.drop db1
82
- expect(tenant_names).not_to include(db1)
83
- end
84
- end
85
-
86
- describe "#switch!" do
87
- it "should connect to new db" do
88
- subject.switch!(db1)
89
- expect(subject.current).to eq(db1)
90
- end
91
-
92
- it "should reset connection if database is nil" do
93
- subject.switch!
94
- expect(subject.current).to eq(default_tenant)
95
- end
96
-
97
- it "should raise an error if database is invalid" do
98
- expect {
99
- subject.switch! 'unknown_database'
100
- }.to raise_error(Apartment::ApartmentError)
101
- end
102
- end
103
-
104
- describe "#switch" do
105
- it "connects and resets the tenant" do
106
- subject.switch(db1) do
107
- expect(subject.current).to eq(db1)
108
- end
109
- expect(subject.current).to eq(default_tenant)
110
- end
111
-
112
- # We're often finding when using Apartment in tests, the `current` (ie the previously connect to db)
113
- # gets dropped, but switch will try to return to that db in a test. We should just reset if it doesn't exist
114
- it "should not throw exception if current is no longer accessible" do
115
- subject.switch!(db2)
116
-
117
- expect {
118
- subject.switch(db1){ subject.drop(db2) }
119
- }.to_not raise_error
120
- end
121
- end
122
-
123
- describe "#reset" do
124
- it "should reset connection" do
125
- subject.switch!(db1)
126
- subject.reset
127
- expect(subject.current).to eq(default_tenant)
128
- end
129
- end
130
-
131
- describe "#current" do
132
- it "should return the current db name" do
133
- subject.switch!(db1)
134
- expect(subject.current).to eq(db1)
135
- end
136
- end
137
-
138
- describe "#each" do
139
- it "iterates over each tenant by default" do
140
- result = []
141
- Apartment.tenant_names = [db2, db1]
142
-
143
- subject.each do |tenant|
144
- result << tenant
145
- expect(subject.current).to eq(tenant)
146
- end
147
-
148
- expect(result).to eq([db2, db1])
149
- end
150
-
151
- it "iterates over the given tenants" do
152
- result = []
153
- Apartment.tenant_names = [db2]
154
-
155
- subject.each([db2]) do |tenant|
156
- result << tenant
157
- expect(subject.current).to eq(tenant)
158
- end
159
-
160
- expect(result).to eq([db2])
161
- end
162
- end
163
- end
@@ -1,234 +0,0 @@
1
- require 'spec_helper'
2
-
3
- shared_examples_for "a schema based apartment adapter" do
4
- include Apartment::Spec::AdapterRequirements
5
-
6
- let(:schema1){ db1 }
7
- let(:schema2){ db2 }
8
- let(:public_schema){ default_tenant }
9
-
10
- describe "#init" do
11
-
12
- before do
13
- Apartment.configure do |config|
14
- config.excluded_models = ["Company"]
15
- end
16
- end
17
-
18
- after do
19
- # Apartment::Tenant.init creates per model connection.
20
- # Remove the connection after testing not to unintentionally keep the connection across tests.
21
- Apartment.excluded_models.each do |excluded_model|
22
- excluded_model.constantize.remove_connection
23
- end
24
- end
25
-
26
- it "should process model exclusions" do
27
- Apartment::Tenant.init
28
-
29
- expect(Company.table_name).to eq("public.companies")
30
- end
31
-
32
- context "with a default_schema", :default_schema => true do
33
-
34
- it "should set the proper table_name on excluded_models" do
35
- Apartment::Tenant.init
36
-
37
- expect(Company.table_name).to eq("#{default_schema}.companies")
38
- end
39
-
40
- it 'sets the search_path correctly' do
41
- Apartment::Tenant.init
42
-
43
- expect(User.connection.schema_search_path).to match(%r|#{default_schema}|)
44
- end
45
- end
46
-
47
- context "persistent_schemas", :persistent_schemas => true do
48
- it "sets the persistent schemas in the schema_search_path" do
49
- Apartment::Tenant.init
50
- expect(connection.schema_search_path).to end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
51
- end
52
- end
53
- end
54
-
55
- #
56
- # Creates happen already in our before_filter
57
- #
58
- describe "#create" do
59
-
60
- it "should load schema.rb to new schema" do
61
- connection.schema_search_path = schema1
62
- expect(connection.tables).to include('companies')
63
- end
64
-
65
- it "should yield to block if passed and reset" do
66
- subject.drop(schema2) # so we don't get errors on creation
67
-
68
- @count = 0 # set our variable so its visible in and outside of blocks
69
-
70
- subject.create(schema2) do
71
- @count = User.count
72
- expect(connection.schema_search_path).to start_with %{"#{schema2}"}
73
- User.create
74
- end
75
-
76
- expect(connection.schema_search_path).not_to start_with %{"#{schema2}"}
77
-
78
- subject.switch(schema2){ expect(User.count).to eq(@count + 1) }
79
- end
80
-
81
- context "numeric database names" do
82
- let(:db){ 1234 }
83
- it "should allow them" do
84
- expect {
85
- subject.create(db)
86
- }.to_not raise_error
87
- expect(tenant_names).to include(db.to_s)
88
- end
89
-
90
- after{ subject.drop(db) }
91
- end
92
-
93
- end
94
-
95
- describe "#drop" do
96
- it "should raise an error for unknown database" do
97
- expect {
98
- subject.drop "unknown_database"
99
- }.to raise_error(Apartment::TenantNotFound)
100
- end
101
-
102
- context "numeric database names" do
103
- let(:db){ 1234 }
104
-
105
- it "should be able to drop them" do
106
- subject.create(db)
107
- expect {
108
- subject.drop(db)
109
- }.to_not raise_error
110
- expect(tenant_names).not_to include(db.to_s)
111
- end
112
-
113
- after { subject.drop(db) rescue nil }
114
- end
115
- end
116
-
117
- describe "#switch" do
118
- it "connects and resets" do
119
- subject.switch(schema1) do
120
- expect(connection.schema_search_path).to start_with %{"#{schema1}"}
121
- end
122
-
123
- expect(connection.schema_search_path).to start_with %{"#{public_schema}"}
124
- end
125
- end
126
-
127
- describe "#reset" do
128
- it "should reset connection" do
129
- subject.switch!(schema1)
130
- subject.reset
131
- expect(connection.schema_search_path).to start_with %{"#{public_schema}"}
132
- end
133
-
134
- context "with default_schema", :default_schema => true do
135
- it "should reset to the default schema" do
136
- subject.switch!(schema1)
137
- subject.reset
138
- expect(connection.schema_search_path).to start_with %{"#{default_schema}"}
139
- end
140
- end
141
-
142
- context "persistent_schemas", :persistent_schemas => true do
143
- before do
144
- subject.switch!(schema1)
145
- subject.reset
146
- end
147
-
148
- it "maintains the persistent schemas in the schema_search_path" do
149
- expect(connection.schema_search_path).to end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
150
- end
151
-
152
- context "with default_schema", :default_schema => true do
153
- it "prioritizes the switched schema to front of schema_search_path" do
154
- subject.reset # need to re-call this as the default_schema wasn't set at the time that the above reset ran
155
- expect(connection.schema_search_path).to start_with %{"#{default_schema}"}
156
- end
157
- end
158
- end
159
- end
160
-
161
- describe "#switch!" do
162
- it "should connect to new schema" do
163
- subject.switch!(schema1)
164
- expect(connection.schema_search_path).to start_with %{"#{schema1}"}
165
- end
166
-
167
- it "should reset connection if database is nil" do
168
- subject.switch!
169
- expect(connection.schema_search_path).to eq(%{"#{public_schema}"})
170
- end
171
-
172
- it "should raise an error if schema is invalid" do
173
- expect {
174
- subject.switch! 'unknown_schema'
175
- }.to raise_error(Apartment::TenantNotFound)
176
- end
177
-
178
- context "numeric databases" do
179
- let(:db){ 1234 }
180
-
181
- it "should connect to them" do
182
- subject.create(db)
183
- expect {
184
- subject.switch!(db)
185
- }.to_not raise_error
186
-
187
- expect(connection.schema_search_path).to start_with %{"#{db.to_s}"}
188
- end
189
-
190
- after{ subject.drop(db) }
191
- end
192
-
193
- describe "with default_schema specified", :default_schema => true do
194
- before do
195
- subject.switch!(schema1)
196
- end
197
-
198
- it "should switch out the default schema rather than public" do
199
- expect(connection.schema_search_path).not_to include default_schema
200
- end
201
-
202
- it "should still switch to the switched schema" do
203
- expect(connection.schema_search_path).to start_with %{"#{schema1}"}
204
- end
205
- end
206
-
207
- context "persistent_schemas", :persistent_schemas => true do
208
-
209
- before{ subject.switch!(schema1) }
210
-
211
- it "maintains the persistent schemas in the schema_search_path" do
212
- expect(connection.schema_search_path).to end_with persistent_schemas.map { |schema| %{"#{schema}"} }.join(', ')
213
- end
214
-
215
- it "prioritizes the switched schema to front of schema_search_path" do
216
- expect(connection.schema_search_path).to start_with %{"#{schema1}"}
217
- end
218
- end
219
- end
220
-
221
- describe "#current" do
222
- it "should return the current schema name" do
223
- subject.switch!(schema1)
224
- expect(subject.current).to eq(schema1)
225
- end
226
-
227
- context "persistent_schemas", :persistent_schemas => true do
228
- it "should exlude persistent_schemas" do
229
- subject.switch!(schema1)
230
- expect(subject.current).to eq(schema1)
231
- end
232
- end
233
- end
234
- end