ros-apartment 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +4 -0
- data/.travis.yml +8 -30
- data/Appraisals +4 -17
- data/Gemfile +1 -1
- data/Guardfile +3 -1
- data/README.md +15 -14
- data/Rakefile +34 -22
- data/apartment.gemspec +11 -3
- data/gemfiles/rails_5_0.gemfile +10 -11
- data/gemfiles/rails_5_1.gemfile +10 -11
- data/gemfiles/rails_5_2.gemfile +9 -10
- data/gemfiles/rails_6_0.gemfile +10 -11
- data/gemfiles/rails_master.gemfile +10 -11
- data/lib/apartment/active_record/connection_handling.rb +17 -0
- data/lib/apartment/active_record/internal_metadata.rb +11 -0
- data/lib/apartment/active_record/schema_migration.rb +13 -0
- data/lib/apartment/adapters/abstract_adapter.rb +3 -2
- data/lib/apartment/model.rb +27 -0
- data/lib/apartment/tenant.rb +3 -1
- data/lib/apartment/version.rb +1 -1
- data/lib/apartment.rb +22 -3
- metadata +11 -209
- data/spec/adapters/jdbc_mysql_adapter_spec.rb +0 -20
- data/spec/adapters/jdbc_postgresql_adapter_spec.rb +0 -39
- data/spec/adapters/mysql2_adapter_spec.rb +0 -61
- data/spec/adapters/postgresql_adapter_spec.rb +0 -63
- data/spec/adapters/sqlite3_adapter_spec.rb +0 -101
- data/spec/apartment_spec.rb +0 -13
- data/spec/config/database.yml.sample +0 -49
- data/spec/dummy/Rakefile +0 -7
- data/spec/dummy/app/controllers/application_controller.rb +0 -7
- data/spec/dummy/app/helpers/application_helper.rb +0 -4
- data/spec/dummy/app/models/application_record.rb +0 -6
- data/spec/dummy/app/models/company.rb +0 -5
- data/spec/dummy/app/models/user.rb +0 -5
- data/spec/dummy/app/views/application/index.html.erb +0 -1
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/config/application.rb +0 -51
- data/spec/dummy/config/boot.rb +0 -13
- data/spec/dummy/config/database.yml.sample +0 -44
- data/spec/dummy/config/environment.rb +0 -7
- data/spec/dummy/config/environments/development.rb +0 -29
- data/spec/dummy/config/environments/production.rb +0 -53
- data/spec/dummy/config/environments/test.rb +0 -36
- data/spec/dummy/config/initializers/apartment.rb +0 -6
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -8
- data/spec/dummy/config/initializers/inflections.rb +0 -11
- data/spec/dummy/config/initializers/mime_types.rb +0 -6
- data/spec/dummy/config/initializers/secret_token.rb +0 -9
- data/spec/dummy/config/initializers/session_store.rb +0 -10
- data/spec/dummy/config/locales/en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -5
- data/spec/dummy/config.ru +0 -6
- data/spec/dummy/db/migrate/20110613152810_create_dummy_models.rb +0 -39
- data/spec/dummy/db/migrate/20111202022214_create_table_books.rb +0 -14
- data/spec/dummy/db/migrate/20180415260934_create_public_tokens.rb +0 -13
- data/spec/dummy/db/schema.rb +0 -55
- data/spec/dummy/db/seeds/import.rb +0 -7
- data/spec/dummy/db/seeds.rb +0 -5
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/public/404.html +0 -26
- data/spec/dummy/public/422.html +0 -26
- data/spec/dummy/public/500.html +0 -26
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +0 -8
- data/spec/dummy_engine/.gitignore +0 -8
- data/spec/dummy_engine/Gemfile +0 -15
- data/spec/dummy_engine/Rakefile +0 -34
- data/spec/dummy_engine/bin/rails +0 -12
- data/spec/dummy_engine/config/initializers/apartment.rb +0 -52
- data/spec/dummy_engine/dummy_engine.gemspec +0 -24
- data/spec/dummy_engine/lib/dummy_engine/engine.rb +0 -6
- data/spec/dummy_engine/lib/dummy_engine/version.rb +0 -5
- data/spec/dummy_engine/lib/dummy_engine.rb +0 -6
- data/spec/dummy_engine/test/dummy/Rakefile +0 -6
- data/spec/dummy_engine/test/dummy/config/application.rb +0 -24
- data/spec/dummy_engine/test/dummy/config/boot.rb +0 -7
- data/spec/dummy_engine/test/dummy/config/database.yml +0 -25
- data/spec/dummy_engine/test/dummy/config/environment.rb +0 -7
- data/spec/dummy_engine/test/dummy/config/environments/development.rb +0 -39
- data/spec/dummy_engine/test/dummy/config/environments/production.rb +0 -80
- data/spec/dummy_engine/test/dummy/config/environments/test.rb +0 -41
- data/spec/dummy_engine/test/dummy/config/initializers/assets.rb +0 -10
- data/spec/dummy_engine/test/dummy/config/initializers/backtrace_silencers.rb +0 -8
- data/spec/dummy_engine/test/dummy/config/initializers/cookies_serializer.rb +0 -5
- data/spec/dummy_engine/test/dummy/config/initializers/filter_parameter_logging.rb +0 -6
- data/spec/dummy_engine/test/dummy/config/initializers/inflections.rb +0 -17
- data/spec/dummy_engine/test/dummy/config/initializers/mime_types.rb +0 -5
- data/spec/dummy_engine/test/dummy/config/initializers/session_store.rb +0 -5
- data/spec/dummy_engine/test/dummy/config/initializers/wrap_parameters.rb +0 -16
- data/spec/dummy_engine/test/dummy/config/locales/en.yml +0 -23
- data/spec/dummy_engine/test/dummy/config/routes.rb +0 -58
- data/spec/dummy_engine/test/dummy/config/secrets.yml +0 -22
- data/spec/dummy_engine/test/dummy/config.ru +0 -6
- data/spec/examples/connection_adapter_examples.rb +0 -44
- data/spec/examples/generic_adapter_custom_configuration_example.rb +0 -93
- data/spec/examples/generic_adapter_examples.rb +0 -164
- data/spec/examples/schema_adapter_examples.rb +0 -239
- data/spec/integration/apartment_rake_integration_spec.rb +0 -107
- data/spec/integration/query_caching_spec.rb +0 -83
- data/spec/integration/use_within_an_engine_spec.rb +0 -28
- data/spec/schemas/v1.rb +0 -15
- data/spec/schemas/v2.rb +0 -41
- data/spec/schemas/v3.rb +0 -47
- data/spec/spec_helper.rb +0 -63
- data/spec/support/apartment_helpers.rb +0 -47
- data/spec/support/capybara_sessions.rb +0 -15
- data/spec/support/config.rb +0 -13
- data/spec/support/contexts.rb +0 -54
- data/spec/support/requirements.rb +0 -48
- data/spec/support/setup.rb +0 -46
- data/spec/tasks/apartment_rake_spec.rb +0 -124
- data/spec/tenant_spec.rb +0 -194
- data/spec/unit/config_spec.rb +0 -111
- data/spec/unit/elevators/domain_spec.rb +0 -33
- data/spec/unit/elevators/first_subdomain_spec.rb +0 -26
- data/spec/unit/elevators/generic_spec.rb +0 -55
- data/spec/unit/elevators/host_hash_spec.rb +0 -33
- data/spec/unit/elevators/host_spec.rb +0 -89
- data/spec/unit/elevators/subdomain_spec.rb +0 -77
- data/spec/unit/migrator_spec.rb +0 -78
- data/spec/unit/reloader_spec.rb +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4f9084d6e2d03975a90c0b57dbb180872bdf027b1fbbea6ca7c50aec81ee97b5
|
4
|
+
data.tar.gz: 10ae96d58901ce650fc458ca7451aadc0e726ea2d22fedbc674edbba24ce271c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 35135a59820ac13e528da16dca7abc6376eb4e2e868a2d00a57169effec73a026ae11726202fc9381160fad7d3cabba764253d592db803d0638a79c2fb8360c0
|
7
|
+
data.tar.gz: b320c009ee8017fcd33faa1ec4ec26a6c2a74bbd19434c0d73f52e4c8def1ba37b03af97f8477d6d5c174636bcf3fd11883be1fbb46119ee8f1be31c44384254
|
data/.rubocop.yml
CHANGED
data/.travis.yml
CHANGED
@@ -5,12 +5,11 @@ services:
|
|
5
5
|
- docker
|
6
6
|
rvm:
|
7
7
|
- jruby-9.2.11.0
|
8
|
-
- 2.
|
9
|
-
- 2.
|
10
|
-
- 2.
|
11
|
-
- 2.
|
12
|
-
-
|
13
|
-
- 2.6.2
|
8
|
+
- 2.4.10
|
9
|
+
- 2.5.8
|
10
|
+
- 2.6.6
|
11
|
+
- 2.7.1
|
12
|
+
- jruby-head
|
14
13
|
- ruby-head
|
15
14
|
|
16
15
|
branches:
|
@@ -19,48 +18,27 @@ branches:
|
|
19
18
|
- development
|
20
19
|
|
21
20
|
gemfile:
|
22
|
-
- gemfiles/rails_4_2.gemfile
|
23
21
|
- gemfiles/rails_5_0.gemfile
|
24
22
|
- gemfiles/rails_5_1.gemfile
|
25
23
|
- gemfiles/rails_5_2.gemfile
|
26
24
|
- gemfiles/rails_6_0.gemfile
|
27
25
|
- gemfiles/rails_master.gemfile
|
26
|
+
|
28
27
|
bundler_args: --without local
|
29
28
|
before_install:
|
30
29
|
- sudo /etc/init.d/mysql stop
|
31
30
|
- sudo /etc/init.d/postgresql stop
|
32
31
|
- docker-compose up -d
|
33
|
-
- gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
|
34
|
-
- gem uninstall bundler -v '>= 2' -x || true
|
35
|
-
- gem install bundler -v '< 2'
|
36
32
|
env:
|
37
33
|
RUBY_GC_MALLOC_LIMIT: 90000000
|
38
34
|
RUBY_GC_HEAP_FREE_SLOTS: 200000
|
39
35
|
jobs:
|
40
36
|
allow_failures:
|
41
37
|
- rvm: ruby-head
|
38
|
+
- rvm: jruby-head
|
42
39
|
- gemfile: gemfiles/rails_master.gemfile
|
43
|
-
- rvm: 2.2.9
|
44
|
-
gemfile: gemfiles/rails_5_2.gemfile
|
45
|
-
# JRuby does not provide support for anything below rails 5
|
46
|
-
- rvm: jruby-9.2.11.0
|
47
|
-
gemfile: gemfiles/rails_4_2.gemfile
|
48
40
|
exclude:
|
49
|
-
- rvm: 2.
|
50
|
-
gemfile: gemfiles/rails_5_0.gemfile
|
51
|
-
- rvm: 2.1.9
|
52
|
-
gemfile: gemfiles/rails_5_1.gemfile
|
53
|
-
- rvm: 2.1.9
|
54
|
-
gemfile: gemfiles/rails_5_2.gemfile
|
55
|
-
- rvm: 2.1.9
|
56
|
-
gemfile: gemfiles/rails_6_0.gemfile
|
57
|
-
- rvm: 2.1.9
|
58
|
-
gemfile: gemfiles/rails_master.gemfile
|
59
|
-
- rvm: 2.2.9
|
60
|
-
gemfile: gemfiles/rails_6_0.gemfile
|
61
|
-
- rvm: 2.3.6
|
62
|
-
gemfile: gemfiles/rails_6_0.gemfile
|
63
|
-
- rvm: 2.4.3
|
41
|
+
- rvm: 2.4.10
|
64
42
|
gemfile: gemfiles/rails_6_0.gemfile
|
65
43
|
fast_finish: true
|
66
44
|
cache: bundler
|
data/Appraisals
CHANGED
@@ -1,18 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
appraise 'rails-4-2' do
|
4
|
-
gem 'rails', '~> 4.2.0'
|
5
|
-
platforms :ruby do
|
6
|
-
gem 'pg', '< 1.0.0'
|
7
|
-
gem 'mysql2', '~> 0.4.0'
|
8
|
-
end
|
9
|
-
platforms :jruby do
|
10
|
-
gem 'activerecord-jdbc-adapter', '~> 1.3'
|
11
|
-
gem 'activerecord-jdbcpostgresql-adapter', '~> 1.3'
|
12
|
-
gem 'activerecord-jdbcmysql-adapter', '~> 1.3'
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
3
|
appraise 'rails-5-0' do
|
17
4
|
gem 'rails', '~> 5.0.0'
|
18
5
|
platforms :ruby do
|
@@ -47,14 +34,14 @@ appraise 'rails-5-2' do
|
|
47
34
|
end
|
48
35
|
|
49
36
|
appraise 'rails-6-0' do
|
50
|
-
gem 'rails', '~> 6.0.0
|
37
|
+
gem 'rails', '~> 6.0.0'
|
51
38
|
platforms :ruby do
|
52
39
|
gem 'sqlite3', '~> 1.4'
|
53
40
|
end
|
54
41
|
platforms :jruby do
|
55
|
-
gem 'activerecord-jdbc-adapter', '~> 60.0
|
56
|
-
gem 'activerecord-jdbcpostgresql-adapter', '~> 60.0
|
57
|
-
gem 'activerecord-jdbcmysql-adapter', '~> 60.0
|
42
|
+
gem 'activerecord-jdbc-adapter', '~> 60.0'
|
43
|
+
gem 'activerecord-jdbcpostgresql-adapter', '~> 60.0'
|
44
|
+
gem 'activerecord-jdbcmysql-adapter', '~> 60.0'
|
58
45
|
end
|
59
46
|
end
|
60
47
|
|
data/Gemfile
CHANGED
data/Guardfile
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# A sample Guardfile
|
2
4
|
# More info at https://github.com/guard/guard#readme
|
3
5
|
|
@@ -5,7 +7,7 @@ guard :rspec do
|
|
5
7
|
watch(%r{^spec/.+_spec\.rb$})
|
6
8
|
watch(%r{^lib/apartment/(.+)\.rb$}) { |m| "spec/unit/#{m[1]}_spec.rb" }
|
7
9
|
watch(%r{^lib/apartment/(.+)\.rb$}) { |m| "spec/integration/#{m[1]}_spec.rb" }
|
8
|
-
watch('spec/spec_helper.rb')
|
10
|
+
watch('spec/spec_helper.rb') { 'spec' }
|
9
11
|
|
10
12
|
# # Rails example
|
11
13
|
# watch(%r{^app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
data/README.md
CHANGED
@@ -341,7 +341,20 @@ Rails will always access the 'public' tenant when accessing these models, but no
|
|
341
341
|
|
342
342
|
### Postgresql Schemas
|
343
343
|
|
344
|
-
|
344
|
+
#### Alternative: Creating new schemas by using raw SQL dumps
|
345
|
+
|
346
|
+
Apartment can be forced to use raw SQL dumps insted of `schema.rb` for creating new schemas. Use this when you are using some extra features in postgres that can't be represented in `schema.rb`, like materialized views etc.
|
347
|
+
|
348
|
+
This only applies while using postgres adapter and `config.use_schemas` is set to `true`.
|
349
|
+
(Note: this option doesn't use `db/structure.sql`, it creates SQL dump by executing `pg_dump`)
|
350
|
+
|
351
|
+
Enable this option with:
|
352
|
+
|
353
|
+
```ruby
|
354
|
+
config.use_sql = true
|
355
|
+
```
|
356
|
+
|
357
|
+
### Providing a Different default_schema
|
345
358
|
|
346
359
|
By default, ActiveRecord will use `"$user", public` as the default `schema_search_path`. This can be modified if you wish to use a different default schema be setting:
|
347
360
|
|
@@ -351,7 +364,7 @@ config.default_schema = "some_other_schema"
|
|
351
364
|
|
352
365
|
With that set, all excluded models will use this schema as the table name prefix instead of `public` and `reset` on `Apartment::Tenant` will return to this schema as well.
|
353
366
|
|
354
|
-
|
367
|
+
### Persistent Schemas
|
355
368
|
|
356
369
|
Apartment will normally just switch the `schema_search_path` whole hog to the one passed in. This can lead to problems if you want other schemas to always be searched as well. Enter `persistent_schemas`. You can configure a list of other schemas that will always remain in the search path, while the default gets swapped out:
|
357
370
|
|
@@ -457,18 +470,6 @@ schema in the `search_path` at all times. We won't be able to do this though unt
|
|
457
470
|
also contain the tenanted tables, which is an open issue with no real milestone to be completed.
|
458
471
|
Happy to accept PR's on the matter.
|
459
472
|
|
460
|
-
#### Alternative: Creating new schemas by using raw SQL dumps
|
461
|
-
|
462
|
-
Apartment can be forced to use raw SQL dumps insted of `schema.rb` for creating new schemas. Use this when you are using some extra features in postgres that can't be represented in `schema.rb`, like materialized views etc.
|
463
|
-
|
464
|
-
This only applies while using postgres adapter and `config.use_schemas` is set to `true`.
|
465
|
-
(Note: this option doesn't use `db/structure.sql`, it creates SQL dump by executing `pg_dump`)
|
466
|
-
|
467
|
-
Enable this option with:
|
468
|
-
```ruby
|
469
|
-
config.use_sql = true
|
470
|
-
```
|
471
|
-
|
472
473
|
### Managing Migrations
|
473
474
|
|
474
475
|
In order to migrate all of your tenants (or postgresql schemas) you need to provide a list
|
data/Rakefile
CHANGED
@@ -1,19 +1,25 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'bundler'
|
5
|
+
rescue StandardError
|
6
|
+
'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
2
8
|
Bundler.setup
|
3
9
|
Bundler::GemHelper.install_tasks
|
4
10
|
|
5
11
|
require 'appraisal'
|
6
12
|
|
7
|
-
require
|
8
|
-
require
|
13
|
+
require 'rspec'
|
14
|
+
require 'rspec/core/rake_task'
|
9
15
|
|
10
|
-
RSpec::Core::RakeTask.new(:
|
11
|
-
spec.pattern =
|
16
|
+
RSpec::Core::RakeTask.new(spec: %w[db:copy_credentials db:test:prepare]) do |spec|
|
17
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
12
18
|
# spec.rspec_opts = '--order rand:47078'
|
13
19
|
end
|
14
20
|
|
15
21
|
namespace :spec do
|
16
|
-
[
|
22
|
+
%i[tasks unit adapters integration].each do |type|
|
17
23
|
RSpec::Core::RakeTask.new(type => :spec) do |spec|
|
18
24
|
spec.pattern = "spec/#{type}/**/*_spec.rb"
|
19
25
|
end
|
@@ -27,11 +33,11 @@ task :console do
|
|
27
33
|
Pry.start
|
28
34
|
end
|
29
35
|
|
30
|
-
task :
|
36
|
+
task default: :spec
|
31
37
|
|
32
38
|
namespace :db do
|
33
39
|
namespace :test do
|
34
|
-
task :
|
40
|
+
task prepare: %w[postgres:drop_db postgres:build_db mysql:drop_db mysql:build_db]
|
35
41
|
end
|
36
42
|
|
37
43
|
desc "copy sample database credential files over if real files don't exist"
|
@@ -40,29 +46,33 @@ namespace :db do
|
|
40
46
|
apartment_db_file = 'spec/config/database.yml'
|
41
47
|
rails_db_file = 'spec/dummy/config/database.yml'
|
42
48
|
|
43
|
-
FileUtils.copy(apartment_db_file + '.sample', apartment_db_file, :
|
44
|
-
FileUtils.copy(rails_db_file + '.sample', rails_db_file, :
|
49
|
+
FileUtils.copy(apartment_db_file + '.sample', apartment_db_file, verbose: true) unless File.exist?(apartment_db_file)
|
50
|
+
FileUtils.copy(rails_db_file + '.sample', rails_db_file, verbose: true) unless File.exist?(rails_db_file)
|
45
51
|
end
|
46
52
|
end
|
47
53
|
|
48
54
|
namespace :postgres do
|
49
55
|
require 'active_record'
|
50
|
-
require
|
56
|
+
require File.join(File.dirname(__FILE__), 'spec', 'support', 'config').to_s
|
51
57
|
|
52
58
|
desc 'Build the PostgreSQL test databases'
|
53
59
|
task :build_db do
|
54
60
|
params = []
|
55
|
-
params <<
|
61
|
+
params << '-E UTF8'
|
56
62
|
params << pg_config['database']
|
57
63
|
params << "-U#{pg_config['username']}"
|
58
64
|
params << "-h#{pg_config['host']}" if pg_config['host']
|
59
65
|
params << "-p#{pg_config['port']}" if pg_config['port']
|
60
|
-
|
66
|
+
begin
|
67
|
+
`createdb #{params.join(' ')}`
|
68
|
+
rescue StandardError
|
69
|
+
'test db already exists'
|
70
|
+
end
|
61
71
|
ActiveRecord::Base.establish_connection pg_config
|
62
72
|
migrate
|
63
73
|
end
|
64
74
|
|
65
|
-
desc
|
75
|
+
desc 'drop the PostgreSQL test database'
|
66
76
|
task :drop_db do
|
67
77
|
puts "dropping database #{pg_config['database']}"
|
68
78
|
params = []
|
@@ -70,14 +80,13 @@ namespace :postgres do
|
|
70
80
|
params << "-U#{pg_config['username']}"
|
71
81
|
params << "-h#{pg_config['host']}" if pg_config['host']
|
72
82
|
params << "-p#{pg_config['port']}" if pg_config['port']
|
73
|
-
|
83
|
+
`dropdb #{params.join(' ')}`
|
74
84
|
end
|
75
|
-
|
76
85
|
end
|
77
86
|
|
78
87
|
namespace :mysql do
|
79
88
|
require 'active_record'
|
80
|
-
require
|
89
|
+
require File.join(File.dirname(__FILE__), 'spec', 'support', 'config').to_s
|
81
90
|
|
82
91
|
desc 'Build the MySQL test databases'
|
83
92
|
task :build_db do
|
@@ -86,12 +95,16 @@ namespace :mysql do
|
|
86
95
|
params << "-u #{my_config['username']}" if my_config['username']
|
87
96
|
params << "-p#{my_config['password']}" if my_config['password']
|
88
97
|
params << "--port #{my_config['port']}" if my_config['port']
|
89
|
-
|
98
|
+
begin
|
99
|
+
`mysqladmin #{params.join(' ')} create #{my_config['database']}`
|
100
|
+
rescue StandardError
|
101
|
+
'test db already exists'
|
102
|
+
end
|
90
103
|
ActiveRecord::Base.establish_connection my_config
|
91
104
|
migrate
|
92
105
|
end
|
93
106
|
|
94
|
-
desc
|
107
|
+
desc 'drop the MySQL test database'
|
95
108
|
task :drop_db do
|
96
109
|
puts "dropping database #{my_config['database']}"
|
97
110
|
params = []
|
@@ -99,12 +112,11 @@ namespace :mysql do
|
|
99
112
|
params << "-u #{my_config['username']}" if my_config['username']
|
100
113
|
params << "-p#{my_config['password']}" if my_config['password']
|
101
114
|
params << "--port #{my_config['port']}" if my_config['port']
|
102
|
-
|
115
|
+
`mysqladmin #{params.join(' ')} drop #{my_config['database']} --force`
|
103
116
|
end
|
104
|
-
|
105
117
|
end
|
106
118
|
|
107
|
-
# TODO clean this up
|
119
|
+
# TODO: clean this up
|
108
120
|
def config
|
109
121
|
Apartment::Test.config['connections']
|
110
122
|
end
|
data/apartment.gemspec
CHANGED
@@ -11,7 +11,15 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.summary = 'A Ruby gem for managing database multitenancy. Apartment Gem drop in replacement'
|
12
12
|
s.description = 'Apartment allows Rack applications to deal with database multitenancy through ActiveRecord'
|
13
13
|
s.email = ['ryan@influitive.com', 'brad@influitive.com', 'rui.p.baltazar@gmail.com']
|
14
|
-
|
14
|
+
# Specify which files should be added to the gem when it is released.
|
15
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been
|
16
|
+
# added into git.
|
17
|
+
s.files = Dir.chdir(File.expand_path(__dir__)) do
|
18
|
+
`git ls-files -z`.split("\x0").reject do |f|
|
19
|
+
# NOTE: ignore all test related
|
20
|
+
f.match(%r{^(test|spec|features)/})
|
21
|
+
end
|
22
|
+
end
|
15
23
|
s.executables = s.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
16
24
|
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
17
25
|
s.require_paths = ['lib']
|
@@ -20,13 +28,13 @@ Gem::Specification.new do |s|
|
|
20
28
|
s.licenses = ['MIT']
|
21
29
|
|
22
30
|
# must be >= 3.1.2 due to bug in prepared_statements
|
23
|
-
s.add_dependency 'activerecord', '>=
|
31
|
+
s.add_dependency 'activerecord', '>= 5.0.0', '< 6.1'
|
24
32
|
s.add_dependency 'parallel', '< 2.0'
|
25
33
|
s.add_dependency 'public_suffix', '>= 2.0.5', '< 5.0'
|
26
34
|
s.add_dependency 'rack', '>= 1.3.6', '< 3.0'
|
27
35
|
|
28
36
|
s.add_development_dependency 'appraisal', '~> 2.2'
|
29
|
-
s.add_development_dependency 'bundler', '>= 1.3', '<
|
37
|
+
s.add_development_dependency 'bundler', '>= 1.3', '< 3.0'
|
30
38
|
s.add_development_dependency 'capybara', '~> 2.0'
|
31
39
|
s.add_development_dependency 'rake', '~> 0.9'
|
32
40
|
s.add_development_dependency 'rspec', '~> 3.4'
|
data/gemfiles/rails_5_0.gemfile
CHANGED
@@ -1,24 +1,23 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
# This file was generated by Appraisal
|
4
2
|
|
5
|
-
source
|
3
|
+
source "http://rubygems.org"
|
6
4
|
|
7
|
-
gem
|
5
|
+
gem "perx-rubocop", "~> 0.0.3"
|
6
|
+
gem "rails", "~> 5.0.0"
|
8
7
|
|
9
8
|
group :local do
|
10
|
-
gem
|
11
|
-
gem
|
9
|
+
gem "guard-rspec", "~> 4.2"
|
10
|
+
gem "pry"
|
12
11
|
end
|
13
12
|
|
14
13
|
platforms :ruby do
|
15
|
-
gem
|
14
|
+
gem "pg", "< 1.0.0"
|
16
15
|
end
|
17
16
|
|
18
17
|
platforms :jruby do
|
19
|
-
gem
|
20
|
-
gem
|
21
|
-
gem
|
18
|
+
gem "activerecord-jdbc-adapter", "~> 50.0"
|
19
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 50.0"
|
20
|
+
gem "activerecord-jdbcmysql-adapter", "~> 50.0"
|
22
21
|
end
|
23
22
|
|
24
|
-
gemspec path:
|
23
|
+
gemspec path: "../"
|
data/gemfiles/rails_5_1.gemfile
CHANGED
@@ -1,24 +1,23 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
# This file was generated by Appraisal
|
4
2
|
|
5
|
-
source
|
3
|
+
source "http://rubygems.org"
|
6
4
|
|
7
|
-
gem
|
5
|
+
gem "perx-rubocop", "~> 0.0.3"
|
6
|
+
gem "rails", "~> 5.1.0"
|
8
7
|
|
9
8
|
group :local do
|
10
|
-
gem
|
11
|
-
gem
|
9
|
+
gem "guard-rspec", "~> 4.2"
|
10
|
+
gem "pry"
|
12
11
|
end
|
13
12
|
|
14
13
|
platforms :ruby do
|
15
|
-
gem
|
14
|
+
gem "pg", "< 1.0.0"
|
16
15
|
end
|
17
16
|
|
18
17
|
platforms :jruby do
|
19
|
-
gem
|
20
|
-
gem
|
21
|
-
gem
|
18
|
+
gem "activerecord-jdbc-adapter", "~> 51.0"
|
19
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 51.0"
|
20
|
+
gem "activerecord-jdbcmysql-adapter", "~> 51.0"
|
22
21
|
end
|
23
22
|
|
24
|
-
gemspec path:
|
23
|
+
gemspec path: "../"
|
data/gemfiles/rails_5_2.gemfile
CHANGED
@@ -1,20 +1,19 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
# This file was generated by Appraisal
|
4
2
|
|
5
|
-
source
|
3
|
+
source "http://rubygems.org"
|
6
4
|
|
7
|
-
gem
|
5
|
+
gem "perx-rubocop", "~> 0.0.3"
|
6
|
+
gem "rails", "~> 5.2.0"
|
8
7
|
|
9
8
|
group :local do
|
10
|
-
gem
|
11
|
-
gem
|
9
|
+
gem "guard-rspec", "~> 4.2"
|
10
|
+
gem "pry"
|
12
11
|
end
|
13
12
|
|
14
13
|
platforms :jruby do
|
15
|
-
gem
|
16
|
-
gem
|
17
|
-
gem
|
14
|
+
gem "activerecord-jdbc-adapter", "~> 52.0"
|
15
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 52.0"
|
16
|
+
gem "activerecord-jdbcmysql-adapter", "~> 52.0"
|
18
17
|
end
|
19
18
|
|
20
|
-
gemspec path:
|
19
|
+
gemspec path: "../"
|
data/gemfiles/rails_6_0.gemfile
CHANGED
@@ -1,24 +1,23 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
# This file was generated by Appraisal
|
4
2
|
|
5
|
-
source
|
3
|
+
source "http://rubygems.org"
|
6
4
|
|
7
|
-
gem
|
5
|
+
gem "perx-rubocop", "~> 0.0.3"
|
6
|
+
gem "rails", "~> 6.0.0"
|
8
7
|
|
9
8
|
group :local do
|
10
|
-
gem
|
11
|
-
gem
|
9
|
+
gem "guard-rspec", "~> 4.2"
|
10
|
+
gem "pry"
|
12
11
|
end
|
13
12
|
|
14
13
|
platforms :ruby do
|
15
|
-
gem
|
14
|
+
gem "sqlite3", "~> 1.4"
|
16
15
|
end
|
17
16
|
|
18
17
|
platforms :jruby do
|
19
|
-
gem
|
20
|
-
gem
|
21
|
-
gem
|
18
|
+
gem "activerecord-jdbc-adapter", "~> 60.0"
|
19
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 60.0"
|
20
|
+
gem "activerecord-jdbcmysql-adapter", "~> 60.0"
|
22
21
|
end
|
23
22
|
|
24
|
-
gemspec path:
|
23
|
+
gemspec path: "../"
|
@@ -1,24 +1,23 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
1
|
# This file was generated by Appraisal
|
4
2
|
|
5
|
-
source
|
3
|
+
source "http://rubygems.org"
|
6
4
|
|
7
|
-
gem
|
5
|
+
gem "perx-rubocop", "~> 0.0.3"
|
6
|
+
gem "rails", git: "https://github.com/rails/rails.git"
|
8
7
|
|
9
8
|
group :local do
|
10
|
-
gem
|
11
|
-
gem
|
9
|
+
gem "guard-rspec", "~> 4.2"
|
10
|
+
gem "pry"
|
12
11
|
end
|
13
12
|
|
14
13
|
platforms :ruby do
|
15
|
-
gem
|
14
|
+
gem "sqlite3", "~> 1.4"
|
16
15
|
end
|
17
16
|
|
18
17
|
platforms :jruby do
|
19
|
-
gem
|
20
|
-
gem
|
21
|
-
gem
|
18
|
+
gem "activerecord-jdbc-adapter", "~> 52.0"
|
19
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 52.0"
|
20
|
+
gem "activerecord-jdbcmysql-adapter", "~> 52.0"
|
22
21
|
end
|
23
22
|
|
24
|
-
gemspec path:
|
23
|
+
gemspec path: "../"
|
@@ -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
|
@@ -103,7 +103,8 @@ module Apartment
|
|
103
103
|
# Establish a new connection for each specific excluded model
|
104
104
|
#
|
105
105
|
def process_excluded_models
|
106
|
-
# All other models will shared a connection (at Apartment.connection_class)
|
106
|
+
# All other models will shared a connection (at Apartment.connection_class)
|
107
|
+
# and we can modify at will
|
107
108
|
Apartment.excluded_models.each do |excluded_model|
|
108
109
|
process_excluded_model(excluded_model)
|
109
110
|
end
|
@@ -230,7 +231,7 @@ module Apartment
|
|
230
231
|
end
|
231
232
|
|
232
233
|
def db_connection_config(tenant)
|
233
|
-
Apartment.db_config_for(tenant).
|
234
|
+
Apartment.db_config_for(tenant).dup
|
234
235
|
end
|
235
236
|
|
236
237
|
def with_neutral_connection(tenant, &_block)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Apartment
|
4
|
+
module Model
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# NOTE: key can either be an array of symbols or a single value.
|
9
|
+
# E.g. If we run the following query:
|
10
|
+
# `Setting.find_by(key: 'something', value: 'amazing')` key will have an array of symbols: `[:key, :something]`
|
11
|
+
# while if we run:
|
12
|
+
# `Setting.find(10)` key will have the value 'id'
|
13
|
+
def cached_find_by_statement(key, &block)
|
14
|
+
# Modifying the cache key to have a reference to the current tenant,
|
15
|
+
# so the cached statement is referring only to the tenant in which we've
|
16
|
+
# executed this
|
17
|
+
cache_key = if key.is_a? String
|
18
|
+
"#{Apartment::Tenant.current}_#{key}"
|
19
|
+
else
|
20
|
+
[Apartment::Tenant.current] + key
|
21
|
+
end
|
22
|
+
cache = @find_by_statement_cache[connection.prepared_statements]
|
23
|
+
cache.compute_if_absent(cache_key) { ActiveRecord::StatementCache.create(connection, &block) }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/apartment/tenant.rb
CHANGED
@@ -9,7 +9,9 @@ module Apartment
|
|
9
9
|
extend self
|
10
10
|
extend Forwardable
|
11
11
|
|
12
|
-
def_delegators :adapter, :create, :drop, :switch, :switch!, :current, :each,
|
12
|
+
def_delegators :adapter, :create, :drop, :switch, :switch!, :current, :each,
|
13
|
+
:reset, :set_callback, :seed, :current_tenant,
|
14
|
+
:default_tenant, :environmentify
|
13
15
|
|
14
16
|
attr_writer :config
|
15
17
|
|