ros-apartment 2.4.0 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
|