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.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -0
  3. data/.travis.yml +8 -30
  4. data/Appraisals +4 -17
  5. data/Gemfile +1 -1
  6. data/Guardfile +3 -1
  7. data/README.md +15 -14
  8. data/Rakefile +34 -22
  9. data/apartment.gemspec +11 -3
  10. data/gemfiles/rails_5_0.gemfile +10 -11
  11. data/gemfiles/rails_5_1.gemfile +10 -11
  12. data/gemfiles/rails_5_2.gemfile +9 -10
  13. data/gemfiles/rails_6_0.gemfile +10 -11
  14. data/gemfiles/rails_master.gemfile +10 -11
  15. data/lib/apartment/active_record/connection_handling.rb +17 -0
  16. data/lib/apartment/active_record/internal_metadata.rb +11 -0
  17. data/lib/apartment/active_record/schema_migration.rb +13 -0
  18. data/lib/apartment/adapters/abstract_adapter.rb +3 -2
  19. data/lib/apartment/model.rb +27 -0
  20. data/lib/apartment/tenant.rb +3 -1
  21. data/lib/apartment/version.rb +1 -1
  22. data/lib/apartment.rb +22 -3
  23. metadata +11 -209
  24. data/spec/adapters/jdbc_mysql_adapter_spec.rb +0 -20
  25. data/spec/adapters/jdbc_postgresql_adapter_spec.rb +0 -39
  26. data/spec/adapters/mysql2_adapter_spec.rb +0 -61
  27. data/spec/adapters/postgresql_adapter_spec.rb +0 -63
  28. data/spec/adapters/sqlite3_adapter_spec.rb +0 -101
  29. data/spec/apartment_spec.rb +0 -13
  30. data/spec/config/database.yml.sample +0 -49
  31. data/spec/dummy/Rakefile +0 -7
  32. data/spec/dummy/app/controllers/application_controller.rb +0 -7
  33. data/spec/dummy/app/helpers/application_helper.rb +0 -4
  34. data/spec/dummy/app/models/application_record.rb +0 -6
  35. data/spec/dummy/app/models/company.rb +0 -5
  36. data/spec/dummy/app/models/user.rb +0 -5
  37. data/spec/dummy/app/views/application/index.html.erb +0 -1
  38. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  39. data/spec/dummy/config/application.rb +0 -51
  40. data/spec/dummy/config/boot.rb +0 -13
  41. data/spec/dummy/config/database.yml.sample +0 -44
  42. data/spec/dummy/config/environment.rb +0 -7
  43. data/spec/dummy/config/environments/development.rb +0 -29
  44. data/spec/dummy/config/environments/production.rb +0 -53
  45. data/spec/dummy/config/environments/test.rb +0 -36
  46. data/spec/dummy/config/initializers/apartment.rb +0 -6
  47. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -8
  48. data/spec/dummy/config/initializers/inflections.rb +0 -11
  49. data/spec/dummy/config/initializers/mime_types.rb +0 -6
  50. data/spec/dummy/config/initializers/secret_token.rb +0 -9
  51. data/spec/dummy/config/initializers/session_store.rb +0 -10
  52. data/spec/dummy/config/locales/en.yml +0 -5
  53. data/spec/dummy/config/routes.rb +0 -5
  54. data/spec/dummy/config.ru +0 -6
  55. data/spec/dummy/db/migrate/20110613152810_create_dummy_models.rb +0 -39
  56. data/spec/dummy/db/migrate/20111202022214_create_table_books.rb +0 -14
  57. data/spec/dummy/db/migrate/20180415260934_create_public_tokens.rb +0 -13
  58. data/spec/dummy/db/schema.rb +0 -55
  59. data/spec/dummy/db/seeds/import.rb +0 -7
  60. data/spec/dummy/db/seeds.rb +0 -5
  61. data/spec/dummy/db/test.sqlite3 +0 -0
  62. data/spec/dummy/public/404.html +0 -26
  63. data/spec/dummy/public/422.html +0 -26
  64. data/spec/dummy/public/500.html +0 -26
  65. data/spec/dummy/public/favicon.ico +0 -0
  66. data/spec/dummy/public/stylesheets/.gitkeep +0 -0
  67. data/spec/dummy/script/rails +0 -8
  68. data/spec/dummy_engine/.gitignore +0 -8
  69. data/spec/dummy_engine/Gemfile +0 -15
  70. data/spec/dummy_engine/Rakefile +0 -34
  71. data/spec/dummy_engine/bin/rails +0 -12
  72. data/spec/dummy_engine/config/initializers/apartment.rb +0 -52
  73. data/spec/dummy_engine/dummy_engine.gemspec +0 -24
  74. data/spec/dummy_engine/lib/dummy_engine/engine.rb +0 -6
  75. data/spec/dummy_engine/lib/dummy_engine/version.rb +0 -5
  76. data/spec/dummy_engine/lib/dummy_engine.rb +0 -6
  77. data/spec/dummy_engine/test/dummy/Rakefile +0 -6
  78. data/spec/dummy_engine/test/dummy/config/application.rb +0 -24
  79. data/spec/dummy_engine/test/dummy/config/boot.rb +0 -7
  80. data/spec/dummy_engine/test/dummy/config/database.yml +0 -25
  81. data/spec/dummy_engine/test/dummy/config/environment.rb +0 -7
  82. data/spec/dummy_engine/test/dummy/config/environments/development.rb +0 -39
  83. data/spec/dummy_engine/test/dummy/config/environments/production.rb +0 -80
  84. data/spec/dummy_engine/test/dummy/config/environments/test.rb +0 -41
  85. data/spec/dummy_engine/test/dummy/config/initializers/assets.rb +0 -10
  86. data/spec/dummy_engine/test/dummy/config/initializers/backtrace_silencers.rb +0 -8
  87. data/spec/dummy_engine/test/dummy/config/initializers/cookies_serializer.rb +0 -5
  88. data/spec/dummy_engine/test/dummy/config/initializers/filter_parameter_logging.rb +0 -6
  89. data/spec/dummy_engine/test/dummy/config/initializers/inflections.rb +0 -17
  90. data/spec/dummy_engine/test/dummy/config/initializers/mime_types.rb +0 -5
  91. data/spec/dummy_engine/test/dummy/config/initializers/session_store.rb +0 -5
  92. data/spec/dummy_engine/test/dummy/config/initializers/wrap_parameters.rb +0 -16
  93. data/spec/dummy_engine/test/dummy/config/locales/en.yml +0 -23
  94. data/spec/dummy_engine/test/dummy/config/routes.rb +0 -58
  95. data/spec/dummy_engine/test/dummy/config/secrets.yml +0 -22
  96. data/spec/dummy_engine/test/dummy/config.ru +0 -6
  97. data/spec/examples/connection_adapter_examples.rb +0 -44
  98. data/spec/examples/generic_adapter_custom_configuration_example.rb +0 -93
  99. data/spec/examples/generic_adapter_examples.rb +0 -164
  100. data/spec/examples/schema_adapter_examples.rb +0 -239
  101. data/spec/integration/apartment_rake_integration_spec.rb +0 -107
  102. data/spec/integration/query_caching_spec.rb +0 -83
  103. data/spec/integration/use_within_an_engine_spec.rb +0 -28
  104. data/spec/schemas/v1.rb +0 -15
  105. data/spec/schemas/v2.rb +0 -41
  106. data/spec/schemas/v3.rb +0 -47
  107. data/spec/spec_helper.rb +0 -63
  108. data/spec/support/apartment_helpers.rb +0 -47
  109. data/spec/support/capybara_sessions.rb +0 -15
  110. data/spec/support/config.rb +0 -13
  111. data/spec/support/contexts.rb +0 -54
  112. data/spec/support/requirements.rb +0 -48
  113. data/spec/support/setup.rb +0 -46
  114. data/spec/tasks/apartment_rake_spec.rb +0 -124
  115. data/spec/tenant_spec.rb +0 -194
  116. data/spec/unit/config_spec.rb +0 -111
  117. data/spec/unit/elevators/domain_spec.rb +0 -33
  118. data/spec/unit/elevators/first_subdomain_spec.rb +0 -26
  119. data/spec/unit/elevators/generic_spec.rb +0 -55
  120. data/spec/unit/elevators/host_hash_spec.rb +0 -33
  121. data/spec/unit/elevators/host_spec.rb +0 -89
  122. data/spec/unit/elevators/subdomain_spec.rb +0 -77
  123. data/spec/unit/migrator_spec.rb +0 -78
  124. data/spec/unit/reloader_spec.rb +0 -24
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 885fc6d80e82f41a7e4a0ab4c6aea81859c39ffbc35454394430168c3d82a378
4
- data.tar.gz: 92df175aec9c46552f8d0d68d154fcc89adc3ae40512c3e2ce9ad1c7d891371e
3
+ metadata.gz: 4f9084d6e2d03975a90c0b57dbb180872bdf027b1fbbea6ca7c50aec81ee97b5
4
+ data.tar.gz: 10ae96d58901ce650fc458ca7451aadc0e726ea2d22fedbc674edbba24ce271c
5
5
  SHA512:
6
- metadata.gz: 60a71a3fa90048da38722e43eb60a8345303aa3131127300a9cab4224f9aeaf6e655022b4fce3c1bb49a9f687b98e79949e29a562bac366bed477aae905d6df7
7
- data.tar.gz: 54836f74344304e196678b1d23c07ad9e293f7630651418d9a792cc0d066c619b792e1226426314d8f4969c2e8902321f1f8d47616d0c813f3e09e67b522f99e
6
+ metadata.gz: 35135a59820ac13e528da16dca7abc6376eb4e2e868a2d00a57169effec73a026ae11726202fc9381160fad7d3cabba764253d592db803d0638a79c2fb8360c0
7
+ data.tar.gz: b320c009ee8017fcd33faa1ec4ec26a6c2a74bbd19434c0d73f52e4c8def1ba37b03af97f8477d6d5c174636bcf3fd11883be1fbb46119ee8f1be31c44384254
data/.rubocop.yml CHANGED
@@ -4,6 +4,10 @@ inherit_gem:
4
4
  perx-rubocop:
5
5
  - default.yml
6
6
 
7
+ AllCops:
8
+ Exclude:
9
+ - 'gemfiles/**/*.gemfile'
10
+
7
11
  Style/WordArray:
8
12
  Exclude:
9
13
  - spec/schemas/**/*.rb
data/.travis.yml CHANGED
@@ -5,12 +5,11 @@ services:
5
5
  - docker
6
6
  rvm:
7
7
  - jruby-9.2.11.0
8
- - 2.1.9
9
- - 2.2.9
10
- - 2.3.6
11
- - 2.4.3
12
- - 2.5.0
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.1.9
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.rc1'
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.rc1'
56
- gem 'activerecord-jdbcpostgresql-adapter', '~> 60.0.rc1'
57
- gem 'activerecord-jdbcmysql-adapter', '~> 60.0.rc1'
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
@@ -4,8 +4,8 @@ source 'http://rubygems.org'
4
4
 
5
5
  gemspec
6
6
 
7
- gem 'rails', '>= 3.1.2'
8
7
  gem 'perx-rubocop', '~> 0.0.3'
8
+ gem 'rails', '>= 3.1.2'
9
9
 
10
10
  group :local do
11
11
  gem 'guard-rspec', '~> 4.2'
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') { "spec" }
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
- ## Providing a Different default_schema
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
- ## Persistent Schemas
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
- require 'bundler' rescue 'You must `gem install bundler` and `bundle install` to run rake tasks'
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 "rspec"
8
- require "rspec/core/rake_task"
13
+ require 'rspec'
14
+ require 'rspec/core/rake_task'
9
15
 
10
- RSpec::Core::RakeTask.new(:spec => %w{ db:copy_credentials db:test:prepare }) do |spec|
11
- spec.pattern = "spec/**/*_spec.rb"
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
- [:tasks, :unit, :adapters, :integration].each do |type|
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 :default => :spec
36
+ task default: :spec
31
37
 
32
38
  namespace :db do
33
39
  namespace :test do
34
- task :prepare => %w{postgres:drop_db postgres:build_db mysql:drop_db mysql:build_db}
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, :verbose => true) unless File.exists?(apartment_db_file)
44
- FileUtils.copy(rails_db_file + '.sample', rails_db_file, :verbose => true) unless File.exists?(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 "#{File.join(File.dirname(__FILE__), 'spec', 'support', 'config')}"
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 << "-E UTF8"
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
- %x{ createdb #{params.join(' ')} } rescue "test db already exists"
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 "drop the PostgreSQL test database"
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
- %x{ dropdb #{params.join(' ')} }
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 "#{File.join(File.dirname(__FILE__), 'spec', 'support', 'config')}"
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
- %x{ mysqladmin #{params.join(' ')} create #{my_config['database']} } rescue "test db already exists"
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 "drop the MySQL test database"
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
- %x{ mysqladmin #{params.join(' ')} drop #{my_config['database']} --force}
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
- s.files = `git ls-files`.split($/)
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', '>= 3.1.2', '< 6.1'
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', '< 2.0'
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'
@@ -1,24 +1,23 @@
1
- # frozen_string_literal: true
2
-
3
1
  # This file was generated by Appraisal
4
2
 
5
- source 'http://rubygems.org'
3
+ source "http://rubygems.org"
6
4
 
7
- gem 'rails', '~> 5.0.0'
5
+ gem "perx-rubocop", "~> 0.0.3"
6
+ gem "rails", "~> 5.0.0"
8
7
 
9
8
  group :local do
10
- gem 'guard-rspec', '~> 4.2'
11
- gem 'pry'
9
+ gem "guard-rspec", "~> 4.2"
10
+ gem "pry"
12
11
  end
13
12
 
14
13
  platforms :ruby do
15
- gem 'pg', '< 1.0.0'
14
+ gem "pg", "< 1.0.0"
16
15
  end
17
16
 
18
17
  platforms :jruby do
19
- gem 'activerecord-jdbc-adapter', '~> 50.0'
20
- gem 'activerecord-jdbcmysql-adapter', '~> 50.0'
21
- gem 'activerecord-jdbcpostgresql-adapter', '~> 50.0'
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: "../"
@@ -1,24 +1,23 @@
1
- # frozen_string_literal: true
2
-
3
1
  # This file was generated by Appraisal
4
2
 
5
- source 'http://rubygems.org'
3
+ source "http://rubygems.org"
6
4
 
7
- gem 'rails', '~> 5.1.0'
5
+ gem "perx-rubocop", "~> 0.0.3"
6
+ gem "rails", "~> 5.1.0"
8
7
 
9
8
  group :local do
10
- gem 'guard-rspec', '~> 4.2'
11
- gem 'pry'
9
+ gem "guard-rspec", "~> 4.2"
10
+ gem "pry"
12
11
  end
13
12
 
14
13
  platforms :ruby do
15
- gem 'pg', '< 1.0.0'
14
+ gem "pg", "< 1.0.0"
16
15
  end
17
16
 
18
17
  platforms :jruby do
19
- gem 'activerecord-jdbc-adapter', '~> 51.0'
20
- gem 'activerecord-jdbcmysql-adapter', '~> 51.0'
21
- gem 'activerecord-jdbcpostgresql-adapter', '~> 51.0'
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: "../"
@@ -1,20 +1,19 @@
1
- # frozen_string_literal: true
2
-
3
1
  # This file was generated by Appraisal
4
2
 
5
- source 'http://rubygems.org'
3
+ source "http://rubygems.org"
6
4
 
7
- gem 'rails', '~> 5.2.0'
5
+ gem "perx-rubocop", "~> 0.0.3"
6
+ gem "rails", "~> 5.2.0"
8
7
 
9
8
  group :local do
10
- gem 'guard-rspec', '~> 4.2'
11
- gem 'pry'
9
+ gem "guard-rspec", "~> 4.2"
10
+ gem "pry"
12
11
  end
13
12
 
14
13
  platforms :jruby do
15
- gem 'activerecord-jdbc-adapter', '~> 52.0'
16
- gem 'activerecord-jdbcmysql-adapter', '~> 52.0'
17
- gem 'activerecord-jdbcpostgresql-adapter', '~> 52.0'
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: "../"
@@ -1,24 +1,23 @@
1
- # frozen_string_literal: true
2
-
3
1
  # This file was generated by Appraisal
4
2
 
5
- source 'http://rubygems.org'
3
+ source "http://rubygems.org"
6
4
 
7
- gem 'rails', '~> 6.0.0.rc1'
5
+ gem "perx-rubocop", "~> 0.0.3"
6
+ gem "rails", "~> 6.0.0"
8
7
 
9
8
  group :local do
10
- gem 'guard-rspec', '~> 4.2'
11
- gem 'pry'
9
+ gem "guard-rspec", "~> 4.2"
10
+ gem "pry"
12
11
  end
13
12
 
14
13
  platforms :ruby do
15
- gem 'sqlite3', '~> 1.4'
14
+ gem "sqlite3", "~> 1.4"
16
15
  end
17
16
 
18
17
  platforms :jruby do
19
- gem 'activerecord-jdbc-adapter', '~> 60.0.rc1'
20
- gem 'activerecord-jdbcmysql-adapter', '~> 60.0.rc1'
21
- gem 'activerecord-jdbcpostgresql-adapter', '~> 60.0.rc1'
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 'http://rubygems.org'
3
+ source "http://rubygems.org"
6
4
 
7
- gem 'rails', git: 'https://github.com/rails/rails.git'
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 'guard-rspec', '~> 4.2'
11
- gem 'pry'
9
+ gem "guard-rspec", "~> 4.2"
10
+ gem "pry"
12
11
  end
13
12
 
14
13
  platforms :ruby do
15
- gem 'sqlite3', '~> 1.4'
14
+ gem "sqlite3", "~> 1.4"
16
15
  end
17
16
 
18
17
  platforms :jruby do
19
- gem 'activerecord-jdbc-adapter', '~> 52.0'
20
- gem 'activerecord-jdbcmysql-adapter', '~> 52.0'
21
- gem 'activerecord-jdbcpostgresql-adapter', '~> 52.0'
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) and we can modify at will
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).clone
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
@@ -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, :reset, :set_callback, :seed, :current_tenant, :default_tenant, :environmentify
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