apartment 2.1.0 → 2.2.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 +5 -5
- data/.gitignore +1 -0
- data/.travis.yml +14 -31
- data/Appraisals +40 -9
- data/HISTORY.md +27 -0
- data/README.md +1 -1
- data/Rakefile +14 -2
- data/apartment.gemspec +3 -3
- data/docker-compose.yml +1 -1
- data/gemfiles/rails_4_2.gemfile +11 -0
- data/gemfiles/rails_5_0.gemfile +10 -0
- data/gemfiles/rails_5_1.gemfile +11 -1
- data/gemfiles/rails_5_2.gemfile +18 -0
- data/gemfiles/rails_master.gemfile +6 -0
- data/lib/apartment.rb +6 -2
- data/lib/apartment/adapters/postgresql_adapter.rb +26 -4
- data/lib/apartment/migrator.rb +22 -4
- data/lib/apartment/railtie.rb +6 -1
- data/lib/apartment/version.rb +1 -1
- data/lib/generators/apartment/install/templates/apartment.rb +10 -0
- data/spec/integration/apartment_rake_integration_spec.rb +41 -8
- data/spec/unit/migrator_spec.rb +56 -16
- metadata +10 -11
- data/gemfiles/rails_4_0.gemfile +0 -12
- data/gemfiles/rails_4_1.gemfile +0 -12
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 12cd184ff975b1b35f44289fb83ffc7a6a644035f90ea4c01fc93d249b814ef2
|
|
4
|
+
data.tar.gz: 448a27893a2ca2564d368c1ca7140582ddcedbb3f209f07f7a8b2e148bfd252e
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: ff5cdb7a876920cbf88f1f5d0cd9821b91de5e518a0eea3eae262552fc6ca1608227ce6f1d2d367f1dca8d97d660f081c61bf89a1ecf2709eb38f8c85582a251
|
|
7
|
+
data.tar.gz: b84c9287ca34937c46dfb6ec9746d6eadd27e81def1f0016b37281f8007a75092d2d58a4826f94da307bf4c75caf4b0b7d0725a478b3ec70c3b92dc8c4b8f5c0
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
|
@@ -1,18 +1,17 @@
|
|
|
1
1
|
language: ruby
|
|
2
2
|
rvm:
|
|
3
3
|
- 2.1.9
|
|
4
|
-
- 2.2.
|
|
5
|
-
- 2.3.
|
|
6
|
-
- 2.4.
|
|
4
|
+
- 2.2.9
|
|
5
|
+
- 2.3.6
|
|
6
|
+
- 2.4.3
|
|
7
|
+
- 2.5.0
|
|
7
8
|
- ruby-head
|
|
8
|
-
- jruby-9.
|
|
9
|
-
- jruby-9.1.9.0
|
|
9
|
+
- jruby-9.1.15.0
|
|
10
10
|
gemfile:
|
|
11
|
-
- gemfiles/rails_4_0.gemfile
|
|
12
|
-
- gemfiles/rails_4_1.gemfile
|
|
13
11
|
- gemfiles/rails_4_2.gemfile
|
|
14
12
|
- gemfiles/rails_5_0.gemfile
|
|
15
13
|
- gemfiles/rails_5_1.gemfile
|
|
14
|
+
- gemfiles/rails_5_2.gemfile
|
|
16
15
|
- gemfiles/rails_master.gemfile
|
|
17
16
|
bundler_args: --without local
|
|
18
17
|
before_install:
|
|
@@ -24,38 +23,22 @@ matrix:
|
|
|
24
23
|
allow_failures:
|
|
25
24
|
- rvm: ruby-head
|
|
26
25
|
- gemfile: gemfiles/rails_master.gemfile
|
|
26
|
+
- rvm: jruby-9.1.15.0
|
|
27
|
+
gemfile: gemfiles/rails_5_0.gemfile
|
|
27
28
|
exclude:
|
|
28
29
|
- rvm: 2.1.9
|
|
29
30
|
gemfile: gemfiles/rails_5_0.gemfile
|
|
30
31
|
- rvm: 2.1.9
|
|
31
32
|
gemfile: gemfiles/rails_5_1.gemfile
|
|
33
|
+
- rvm: 2.1.9
|
|
34
|
+
gemfile: gemfiles/rails_5_2.gemfile
|
|
32
35
|
- rvm: 2.1.9
|
|
33
36
|
gemfile: gemfiles/rails_master.gemfile
|
|
34
|
-
- rvm:
|
|
35
|
-
gemfile: gemfiles/rails_4_0.gemfile
|
|
36
|
-
- rvm: 2.4.1
|
|
37
|
-
gemfile: gemfiles/rails_4_1.gemfile
|
|
38
|
-
- rvm: ruby-head
|
|
39
|
-
gemfile: gemfiles/rails_4_0.gemfile
|
|
40
|
-
- rvm: ruby-head
|
|
41
|
-
gemfile: gemfiles/rails_4_1.gemfile
|
|
42
|
-
- rvm: jruby-9.0.5.0
|
|
43
|
-
gemfile: gemfiles/rails_4_0.gemfile
|
|
44
|
-
- rvm: jruby-9.0.5.0
|
|
45
|
-
gemfile: gemfiles/rails_4_2.gemfile
|
|
46
|
-
- rvm: jruby-9.0.5.0
|
|
47
|
-
gemfile: gemfiles/rails_5_0.gemfile
|
|
48
|
-
- rvm: jruby-9.0.5.0
|
|
49
|
-
gemfile: gemfiles/rails_5_1.gemfile
|
|
50
|
-
- rvm: jruby-9.0.5.0
|
|
51
|
-
gemfile: gemfiles/rails_master.gemfile
|
|
52
|
-
- rvm: jruby-9.1.9.0
|
|
53
|
-
gemfile: gemfiles/rails_4_0.gemfile
|
|
54
|
-
- rvm: jruby-9.1.9.0
|
|
55
|
-
gemfile: gemfiles/rails_5_0.gemfile
|
|
56
|
-
- rvm: jruby-9.1.9.0
|
|
37
|
+
- rvm: jruby-9.1.15.0
|
|
57
38
|
gemfile: gemfiles/rails_5_1.gemfile
|
|
58
|
-
- rvm: jruby-9.1.
|
|
39
|
+
- rvm: jruby-9.1.15.0
|
|
40
|
+
gemfile: gemfiles/rails_5_2.gemfile
|
|
41
|
+
- rvm: jruby-9.1.15.0
|
|
59
42
|
gemfile: gemfiles/rails_master.gemfile
|
|
60
43
|
fast_finish: true
|
|
61
44
|
cache: bundler
|
data/Appraisals
CHANGED
|
@@ -1,23 +1,54 @@
|
|
|
1
|
-
appraise "rails-4-0" do
|
|
2
|
-
gem "rails", "~> 4.0.0"
|
|
3
|
-
end
|
|
4
|
-
|
|
5
|
-
appraise "rails-4-1" do
|
|
6
|
-
gem "rails", "~> 4.1.0"
|
|
7
|
-
end
|
|
8
|
-
|
|
9
1
|
appraise "rails-4-2" do
|
|
10
2
|
gem "rails", "~> 4.2.0"
|
|
3
|
+
platforms :ruby do
|
|
4
|
+
gem "pg", "< 1.0.0"
|
|
5
|
+
gem "mysql2", "~> 0.4.0"
|
|
6
|
+
end
|
|
7
|
+
platforms :jruby do
|
|
8
|
+
gem 'activerecord-jdbc-adapter', '~> 1.3'
|
|
9
|
+
gem 'activerecord-jdbcpostgresql-adapter', '~> 1.3'
|
|
10
|
+
gem 'activerecord-jdbcmysql-adapter', '~> 1.3'
|
|
11
|
+
end
|
|
11
12
|
end
|
|
12
13
|
|
|
13
14
|
appraise "rails-5-0" do
|
|
14
15
|
gem "rails", "~> 5.0.0"
|
|
16
|
+
platforms :ruby do
|
|
17
|
+
gem "pg", "< 1.0.0"
|
|
18
|
+
end
|
|
19
|
+
platforms :jruby do
|
|
20
|
+
gem 'activerecord-jdbc-adapter', '~> 50.0'
|
|
21
|
+
gem 'activerecord-jdbcpostgresql-adapter', '~> 50.0'
|
|
22
|
+
gem 'activerecord-jdbcmysql-adapter', '~> 50.0'
|
|
23
|
+
end
|
|
15
24
|
end
|
|
16
25
|
|
|
17
26
|
appraise "rails-5-1" do
|
|
18
|
-
gem "rails", "5.1.
|
|
27
|
+
gem "rails", "~> 5.1.0"
|
|
28
|
+
platforms :ruby do
|
|
29
|
+
gem "pg", "< 1.0.0"
|
|
30
|
+
end
|
|
31
|
+
platforms :jruby do
|
|
32
|
+
gem 'activerecord-jdbc-adapter', '~> 51.0'
|
|
33
|
+
gem 'activerecord-jdbcpostgresql-adapter', '~> 51.0'
|
|
34
|
+
gem 'activerecord-jdbcmysql-adapter', '~> 51.0'
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
appraise "rails-5-2" do
|
|
39
|
+
gem "rails", "~> 5.2.0"
|
|
40
|
+
platforms :jruby do
|
|
41
|
+
gem 'activerecord-jdbc-adapter', '~> 51.0'
|
|
42
|
+
gem 'activerecord-jdbcpostgresql-adapter', '~> 51.0'
|
|
43
|
+
gem 'activerecord-jdbcmysql-adapter', '~> 51.0'
|
|
44
|
+
end
|
|
19
45
|
end
|
|
20
46
|
|
|
21
47
|
appraise "rails-master" do
|
|
22
48
|
gem "rails", git: 'https://github.com/rails/rails.git'
|
|
49
|
+
platforms :jruby do
|
|
50
|
+
gem 'activerecord-jdbc-adapter', '~> 51.0'
|
|
51
|
+
gem 'activerecord-jdbcpostgresql-adapter', '~> 51.0'
|
|
52
|
+
gem 'activerecord-jdbcmysql-adapter', '~> 51.0'
|
|
53
|
+
end
|
|
23
54
|
end
|
data/HISTORY.md
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
|
+
# 2.2.0
|
|
2
|
+
* April 14, 2018
|
|
3
|
+
|
|
4
|
+
## Added
|
|
5
|
+
- #523: Add Rails 5.2 support [IngusSkaistkalns]
|
|
6
|
+
- #504: Test against Ruby 2.5.0 [ahorek]
|
|
7
|
+
- #528: Test against Rails 5.2 [meganemura]
|
|
8
|
+
|
|
9
|
+
## Removed
|
|
10
|
+
- #504: Remove Rails 4.0/4.1 support [ahorek]
|
|
11
|
+
- #545: Stop supporting for JRuby + Rails 5.0 [meganemura]
|
|
12
|
+
|
|
13
|
+
## Fixed
|
|
14
|
+
- #537: Fix PostgresqlSchemaFromSqlAdapter for newer PostgreSQL [shterrett]
|
|
15
|
+
- #532: Issue is reported by [aldrinmartoq]
|
|
16
|
+
- #519: Fix exception when main database doesn't exist [mayeco]
|
|
17
|
+
|
|
18
|
+
## Changed
|
|
19
|
+
- #514: Fix typo [menorval]
|
|
20
|
+
|
|
1
21
|
# 2.1.0
|
|
2
22
|
* December 15, 2017
|
|
3
23
|
|
|
24
|
+
- Add `parallel_migration_threads` configuration option for running migrations
|
|
25
|
+
in parallel [ryanbrunner]
|
|
26
|
+
- Drop Ruby 2.0.0 support [meganemura]
|
|
27
|
+
- ignore_private when parsing subdomains with PublicSuffix [michiomochi]
|
|
28
|
+
- Ignore row_security statements in psql dumps for backward compatibility
|
|
29
|
+
[meganemura]
|
|
30
|
+
- "Host" elevator [shrmnk]
|
|
4
31
|
- Enhance db:drop task to act on all tenants [kuzukuzu]
|
|
5
32
|
|
|
6
33
|
# 2.0.0
|
data/README.md
CHANGED
|
@@ -149,7 +149,7 @@ This functions much in the same way as Apartment.excluded_models. This example w
|
|
|
149
149
|
|
|
150
150
|
#### Switch on first subdomain
|
|
151
151
|
|
|
152
|
-
To switch on the first subdomain, which analyzes the chain of subdomains of the request and switches to a tenant schema of the first name in the chain (e.g. owls.birds.animals.com would switch to "
|
|
152
|
+
To switch on the first subdomain, which analyzes the chain of subdomains of the request and switches to a tenant schema of the first name in the chain (e.g. owls.birds.animals.com would switch to "owls"). It can be used like so:
|
|
153
153
|
|
|
154
154
|
```ruby
|
|
155
155
|
# application.rb
|
data/Rakefile
CHANGED
|
@@ -59,7 +59,7 @@ namespace :postgres do
|
|
|
59
59
|
params << "-p#{pg_config['port']}" if pg_config['port']
|
|
60
60
|
%x{ createdb #{params.join(' ')} } rescue "test db already exists"
|
|
61
61
|
ActiveRecord::Base.establish_connection pg_config
|
|
62
|
-
|
|
62
|
+
migrate
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
desc "drop the PostgreSQL test database"
|
|
@@ -87,7 +87,7 @@ namespace :mysql do
|
|
|
87
87
|
params << "-p#{my_config['password']}" if my_config['password']
|
|
88
88
|
%x{ mysqladmin #{params.join(' ')} create #{my_config['database']} } rescue "test db already exists"
|
|
89
89
|
ActiveRecord::Base.establish_connection my_config
|
|
90
|
-
|
|
90
|
+
migrate
|
|
91
91
|
end
|
|
92
92
|
|
|
93
93
|
desc "drop the MySQL test database"
|
|
@@ -114,3 +114,15 @@ end
|
|
|
114
114
|
def my_config
|
|
115
115
|
config['mysql']
|
|
116
116
|
end
|
|
117
|
+
|
|
118
|
+
def activerecord_below_5_2?
|
|
119
|
+
ActiveRecord.version.release < Gem::Version.new('5.2.0')
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def migrate
|
|
123
|
+
if activerecord_below_5_2?
|
|
124
|
+
ActiveRecord::Migrator.migrate('spec/dummy/db/migrate')
|
|
125
|
+
else
|
|
126
|
+
ActiveRecord::MigrationContext.new('spec/dummy/db/migrate').migrate
|
|
127
|
+
end
|
|
128
|
+
end
|
data/apartment.gemspec
CHANGED
|
@@ -34,12 +34,12 @@ Gem::Specification.new do |s|
|
|
|
34
34
|
s.add_development_dependency 'activerecord-jdbc-adapter'
|
|
35
35
|
s.add_development_dependency 'activerecord-jdbcpostgresql-adapter'
|
|
36
36
|
s.add_development_dependency 'activerecord-jdbcmysql-adapter'
|
|
37
|
-
s.add_development_dependency 'jdbc-postgres'
|
|
37
|
+
s.add_development_dependency 'jdbc-postgres'
|
|
38
38
|
s.add_development_dependency 'jdbc-mysql'
|
|
39
39
|
s.add_development_dependency 'jruby-openssl'
|
|
40
40
|
else
|
|
41
|
-
s.add_development_dependency 'mysql2'
|
|
42
|
-
s.add_development_dependency 'pg'
|
|
41
|
+
s.add_development_dependency 'mysql2'
|
|
42
|
+
s.add_development_dependency 'pg'
|
|
43
43
|
s.add_development_dependency 'sqlite3'
|
|
44
44
|
end
|
|
45
45
|
end
|
data/docker-compose.yml
CHANGED
data/gemfiles/rails_4_2.gemfile
CHANGED
|
@@ -9,4 +9,15 @@ group :local do
|
|
|
9
9
|
gem "guard-rspec", "~> 4.2"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
platforms :ruby do
|
|
13
|
+
gem "pg", "< 1.0.0"
|
|
14
|
+
gem "mysql2", "~> 0.4.0"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
platforms :jruby do
|
|
18
|
+
gem "activerecord-jdbc-adapter", "~> 1.3"
|
|
19
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 1.3"
|
|
20
|
+
gem "activerecord-jdbcmysql-adapter", "~> 1.3"
|
|
21
|
+
end
|
|
22
|
+
|
|
12
23
|
gemspec path: "../"
|
data/gemfiles/rails_5_0.gemfile
CHANGED
|
@@ -9,4 +9,14 @@ group :local do
|
|
|
9
9
|
gem "guard-rspec", "~> 4.2"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
platforms :ruby do
|
|
13
|
+
gem "pg", "< 1.0.0"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
platforms :jruby do
|
|
17
|
+
gem "activerecord-jdbc-adapter", "~> 50.0"
|
|
18
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 50.0"
|
|
19
|
+
gem "activerecord-jdbcmysql-adapter", "~> 50.0"
|
|
20
|
+
end
|
|
21
|
+
|
|
12
22
|
gemspec path: "../"
|
data/gemfiles/rails_5_1.gemfile
CHANGED
|
@@ -2,11 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
source "http://rubygems.org"
|
|
4
4
|
|
|
5
|
-
gem "rails", "5.1.
|
|
5
|
+
gem "rails", "~> 5.1.0"
|
|
6
6
|
|
|
7
7
|
group :local do
|
|
8
8
|
gem "pry"
|
|
9
9
|
gem "guard-rspec", "~> 4.2"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
platforms :ruby do
|
|
13
|
+
gem "pg", "< 1.0.0"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
platforms :jruby do
|
|
17
|
+
gem "activerecord-jdbc-adapter", "~> 51.0"
|
|
18
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 51.0"
|
|
19
|
+
gem "activerecord-jdbcmysql-adapter", "~> 51.0"
|
|
20
|
+
end
|
|
21
|
+
|
|
12
22
|
gemspec path: "../"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# This file was generated by Appraisal
|
|
2
|
+
|
|
3
|
+
source "http://rubygems.org"
|
|
4
|
+
|
|
5
|
+
gem "rails", "~> 5.2.0"
|
|
6
|
+
|
|
7
|
+
group :local do
|
|
8
|
+
gem "pry"
|
|
9
|
+
gem "guard-rspec", "~> 4.2"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
platforms :jruby do
|
|
13
|
+
gem "activerecord-jdbc-adapter", "~> 51.0"
|
|
14
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 51.0"
|
|
15
|
+
gem "activerecord-jdbcmysql-adapter", "~> 51.0"
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
gemspec path: "../"
|
|
@@ -9,4 +9,10 @@ group :local do
|
|
|
9
9
|
gem "guard-rspec", "~> 4.2"
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
+
platforms :jruby do
|
|
13
|
+
gem "activerecord-jdbc-adapter", "~> 51.0"
|
|
14
|
+
gem "activerecord-jdbcpostgresql-adapter", "~> 51.0"
|
|
15
|
+
gem "activerecord-jdbcmysql-adapter", "~> 51.0"
|
|
16
|
+
end
|
|
17
|
+
|
|
12
18
|
gemspec path: "../"
|
data/lib/apartment.rb
CHANGED
|
@@ -10,8 +10,8 @@ module Apartment
|
|
|
10
10
|
|
|
11
11
|
extend Forwardable
|
|
12
12
|
|
|
13
|
-
ACCESSOR_METHODS = [:use_schemas, :use_sql, :seed_after_create, :prepend_environment, :append_environment, :with_multi_server_setup
|
|
14
|
-
WRITER_METHODS = [:tenant_names, :database_schema_file, :excluded_models, :default_schema, :persistent_schemas, :connection_class, :tld_length, :db_migrate_tenants, :seed_data_file, :parallel_migration_threads]
|
|
13
|
+
ACCESSOR_METHODS = [:use_schemas, :use_sql, :seed_after_create, :prepend_environment, :append_environment, :with_multi_server_setup]
|
|
14
|
+
WRITER_METHODS = [:tenant_names, :database_schema_file, :excluded_models, :default_schema, :persistent_schemas, :connection_class, :tld_length, :db_migrate_tenants, :seed_data_file, :parallel_migration_threads, :pg_excluded_names]
|
|
15
15
|
|
|
16
16
|
attr_accessor(*ACCESSOR_METHODS)
|
|
17
17
|
attr_writer(*WRITER_METHODS)
|
|
@@ -78,6 +78,10 @@ module Apartment
|
|
|
78
78
|
@seed_data_file = "#{Rails.root}/db/seeds.rb"
|
|
79
79
|
end
|
|
80
80
|
|
|
81
|
+
def pg_excluded_names
|
|
82
|
+
@pg_excluded_names || []
|
|
83
|
+
end
|
|
84
|
+
|
|
81
85
|
# Reset all the config for Apartment
|
|
82
86
|
def reset
|
|
83
87
|
(ACCESSOR_METHODS + WRITER_METHODS).each{|method| remove_instance_variable(:"@#{method}") if instance_variable_defined?(:"@#{method}") }
|
|
@@ -113,12 +113,24 @@ module Apartment
|
|
|
113
113
|
]
|
|
114
114
|
|
|
115
115
|
def import_database_schema
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
preserving_search_path do
|
|
117
|
+
clone_pg_schema
|
|
118
|
+
copy_schema_migrations
|
|
119
|
+
end
|
|
118
120
|
end
|
|
119
121
|
|
|
120
122
|
private
|
|
121
123
|
|
|
124
|
+
# Re-set search path after the schema is imported.
|
|
125
|
+
# Postgres now sets search path to empty before dumping the schema
|
|
126
|
+
# and it mut be reset
|
|
127
|
+
#
|
|
128
|
+
def preserving_search_path
|
|
129
|
+
search_path = Apartment.connection.execute("show search_path").first["search_path"]
|
|
130
|
+
yield
|
|
131
|
+
Apartment.connection.execute("set search_path = #{search_path}")
|
|
132
|
+
end
|
|
133
|
+
|
|
122
134
|
# Clone default schema into new schema named after current tenant
|
|
123
135
|
#
|
|
124
136
|
def clone_pg_schema
|
|
@@ -155,7 +167,7 @@ module Apartment
|
|
|
155
167
|
# @return {String} raw SQL contaning inserts with data from schema_migrations
|
|
156
168
|
#
|
|
157
169
|
def pg_dump_schema_migrations_data
|
|
158
|
-
with_pg_env { `pg_dump -a --inserts -t schema_migrations -t
|
|
170
|
+
with_pg_env { `pg_dump -a --inserts -t #{default_tenant}.schema_migrations -t #{default_tenant}.ar_internal_metadata #{dbname}` }
|
|
159
171
|
end
|
|
160
172
|
|
|
161
173
|
# Temporary set Postgresql related environment variables if there are in @config
|
|
@@ -180,13 +192,23 @@ module Apartment
|
|
|
180
192
|
def patch_search_path(sql)
|
|
181
193
|
search_path = "SET search_path = \"#{current}\", #{default_tenant};"
|
|
182
194
|
|
|
183
|
-
sql
|
|
195
|
+
swap_schema_qualifier(sql)
|
|
184
196
|
.split("\n")
|
|
185
197
|
.select {|line| check_input_against_regexps(line, PSQL_DUMP_BLACKLISTED_STATEMENTS).empty?}
|
|
186
198
|
.prepend(search_path)
|
|
187
199
|
.join("\n")
|
|
188
200
|
end
|
|
189
201
|
|
|
202
|
+
def swap_schema_qualifier(sql)
|
|
203
|
+
sql.gsub(/#{default_tenant}\.\w*/) do |match|
|
|
204
|
+
if Apartment.pg_excluded_names.any? { |name| match.include? name }
|
|
205
|
+
match
|
|
206
|
+
else
|
|
207
|
+
match.gsub(default_tenant, %{"#{current}"})
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
end
|
|
211
|
+
|
|
190
212
|
# Checks if any of regexps matches against input
|
|
191
213
|
#
|
|
192
214
|
def check_input_against_regexps(input, regexps)
|
data/lib/apartment/migrator.rb
CHANGED
|
@@ -10,8 +10,12 @@ module Apartment
|
|
|
10
10
|
Tenant.switch(database) do
|
|
11
11
|
version = ENV["VERSION"] ? ENV["VERSION"].to_i : nil
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
migration_scope_block = -> (migration) { ENV["SCOPE"].blank? || (ENV["SCOPE"] == migration.scope) }
|
|
14
|
+
|
|
15
|
+
if activerecord_below_5_2?
|
|
16
|
+
ActiveRecord::Migrator.migrate(ActiveRecord::Migrator.migrations_paths, version, &migration_scope_block)
|
|
17
|
+
else
|
|
18
|
+
ActiveRecord::Base.connection.migration_context.migrate(version, &migration_scope_block)
|
|
15
19
|
end
|
|
16
20
|
end
|
|
17
21
|
end
|
|
@@ -19,15 +23,29 @@ module Apartment
|
|
|
19
23
|
# Migrate up/down to a specific version
|
|
20
24
|
def run(direction, database, version)
|
|
21
25
|
Tenant.switch(database) do
|
|
22
|
-
|
|
26
|
+
if activerecord_below_5_2?
|
|
27
|
+
ActiveRecord::Migrator.run(direction, ActiveRecord::Migrator.migrations_paths, version)
|
|
28
|
+
else
|
|
29
|
+
ActiveRecord::Base.connection.migration_context.run(direction, version)
|
|
30
|
+
end
|
|
23
31
|
end
|
|
24
32
|
end
|
|
25
33
|
|
|
26
34
|
# rollback latest migration `step` number of times
|
|
27
35
|
def rollback(database, step = 1)
|
|
28
36
|
Tenant.switch(database) do
|
|
29
|
-
|
|
37
|
+
if activerecord_below_5_2?
|
|
38
|
+
ActiveRecord::Migrator.rollback(ActiveRecord::Migrator.migrations_paths, step)
|
|
39
|
+
else
|
|
40
|
+
ActiveRecord::Base.connection.migration_context.rollback(step)
|
|
41
|
+
end
|
|
30
42
|
end
|
|
31
43
|
end
|
|
44
|
+
|
|
45
|
+
private
|
|
46
|
+
|
|
47
|
+
def activerecord_below_5_2?
|
|
48
|
+
ActiveRecord.version.release < Gem::Version.new('5.2.0')
|
|
49
|
+
end
|
|
32
50
|
end
|
|
33
51
|
end
|
data/lib/apartment/railtie.rb
CHANGED
|
@@ -27,10 +27,15 @@ module Apartment
|
|
|
27
27
|
# See the middleware/console declarations below to help with this. Hope to fix that soon.
|
|
28
28
|
#
|
|
29
29
|
config.to_prepare do
|
|
30
|
-
|
|
30
|
+
next if ARGV.any? { |arg| arg =~ /\Aassets:(?:precompile|clean)\z/ }
|
|
31
|
+
|
|
32
|
+
begin
|
|
31
33
|
Apartment.connection_class.connection_pool.with_connection do
|
|
32
34
|
Apartment::Tenant.init
|
|
33
35
|
end
|
|
36
|
+
rescue ::ActiveRecord::NoDatabaseError
|
|
37
|
+
# Since `db:create` and other tasks invoke this block from Rails 5.2.0,
|
|
38
|
+
# we need to swallow the error to execute `db:create` properly.
|
|
34
39
|
end
|
|
35
40
|
end
|
|
36
41
|
|
data/lib/apartment/version.rb
CHANGED
|
@@ -85,6 +85,16 @@ Apartment.configure do |config|
|
|
|
85
85
|
# Uncomment the line below if you want to disable this behaviour in production.
|
|
86
86
|
#
|
|
87
87
|
# config.prepend_environment = !Rails.env.production?
|
|
88
|
+
|
|
89
|
+
# When using PostgreSQL schemas, the database dump will be namespaced, and
|
|
90
|
+
# apartment will substitute the default namespace (usually public) with the
|
|
91
|
+
# name of the new tenant when creating a new tenant. Some items must maintain
|
|
92
|
+
# a reference to the default namespace (ie public) - for instance, a default
|
|
93
|
+
# uuid generation. Uncomment the line below to create a list of namespaced
|
|
94
|
+
# items in the schema dump that should *not* have their namespace replaced by
|
|
95
|
+
# the new tenant
|
|
96
|
+
#
|
|
97
|
+
# config.pg_excluded_names = ["uuid_generate_v4"]
|
|
88
98
|
end
|
|
89
99
|
|
|
90
100
|
# Setup a custom Tenant switching middleware. The Proc should return the name of the Tenant that
|
|
@@ -47,19 +47,52 @@ describe "apartment rake tasks", database: :postgresql do
|
|
|
47
47
|
Company.delete_all
|
|
48
48
|
end
|
|
49
49
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
50
|
+
context "with ActiveRecord below 5.2.0" do
|
|
51
|
+
before do
|
|
52
|
+
allow(ActiveRecord::Migrator).to receive(:migrations_paths) { %w(spec/dummy/db/migrate) }
|
|
53
|
+
allow(Apartment::Migrator).to receive(:activerecord_below_5_2?) { true }
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
describe "#migrate" do
|
|
57
|
+
it "should migrate all databases" do
|
|
58
|
+
expect(ActiveRecord::Migrator).to receive(:migrate).exactly(company_count).times
|
|
59
|
+
|
|
60
|
+
@rake['apartment:migrate'].invoke
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
describe "#rollback" do
|
|
65
|
+
it "should rollback all dbs" do
|
|
66
|
+
expect(ActiveRecord::Migrator).to receive(:rollback).exactly(company_count).times
|
|
53
67
|
|
|
54
|
-
|
|
68
|
+
@rake['apartment:rollback'].invoke
|
|
69
|
+
end
|
|
55
70
|
end
|
|
56
71
|
end
|
|
57
72
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
73
|
+
context "with ActiveRecord above or equal to 5.2.0" do
|
|
74
|
+
let(:migration_context_double) { double(:migration_context) }
|
|
75
|
+
|
|
76
|
+
before do
|
|
77
|
+
allow(Apartment::Migrator).to receive(:activerecord_below_5_2?) { false }
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe "#migrate" do
|
|
81
|
+
it "should migrate all databases" do
|
|
82
|
+
allow(ActiveRecord::Base.connection).to receive(:migration_context) { migration_context_double }
|
|
83
|
+
expect(migration_context_double).to receive(:migrate).exactly(company_count).times
|
|
84
|
+
|
|
85
|
+
@rake['apartment:migrate'].invoke
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
describe "#rollback" do
|
|
90
|
+
it "should rollback all dbs" do
|
|
91
|
+
allow(ActiveRecord::Base.connection).to receive(:migration_context) { migration_context_double }
|
|
92
|
+
expect(migration_context_double).to receive(:rollback).exactly(company_count).times
|
|
61
93
|
|
|
62
|
-
|
|
94
|
+
@rake['apartment:rollback'].invoke
|
|
95
|
+
end
|
|
63
96
|
end
|
|
64
97
|
end
|
|
65
98
|
|
data/spec/unit/migrator_spec.rb
CHANGED
|
@@ -8,30 +8,70 @@ describe Apartment::Migrator do
|
|
|
8
8
|
# Don't need a real switch here, just testing behaviour
|
|
9
9
|
before { allow(Apartment::Tenant.adapter).to receive(:connect_to_new) }
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
context "with ActiveRecord below 5.2.0", skip: ActiveRecord.version >= Gem::Version.new("5.2.0") do
|
|
12
|
+
before do
|
|
13
|
+
allow(ActiveRecord::Migrator).to receive(:migrations_paths) { %w(spec/dummy/db/migrate) }
|
|
14
|
+
allow(Apartment::Migrator).to receive(:activerecord_below_5_2?) { true }
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
describe "::migrate" do
|
|
18
|
+
it "switches and migrates" do
|
|
19
|
+
expect(Apartment::Tenant).to receive(:switch).with(tenant).and_call_original
|
|
20
|
+
expect(ActiveRecord::Migrator).to receive(:migrate)
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
Apartment::Migrator.migrate(tenant)
|
|
23
|
+
end
|
|
17
24
|
end
|
|
18
|
-
end
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
26
|
+
describe "::run" do
|
|
27
|
+
it "switches and runs" do
|
|
28
|
+
expect(Apartment::Tenant).to receive(:switch).with(tenant).and_call_original
|
|
29
|
+
expect(ActiveRecord::Migrator).to receive(:run).with(:up, anything, 1234)
|
|
24
30
|
|
|
25
|
-
|
|
31
|
+
Apartment::Migrator.run(:up, tenant, 1234)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
describe "::rollback" do
|
|
36
|
+
it "switches and rolls back" do
|
|
37
|
+
expect(Apartment::Tenant).to receive(:switch).with(tenant).and_call_original
|
|
38
|
+
expect(ActiveRecord::Migrator).to receive(:rollback).with(anything, 2)
|
|
39
|
+
|
|
40
|
+
Apartment::Migrator.rollback(tenant, 2)
|
|
41
|
+
end
|
|
26
42
|
end
|
|
27
43
|
end
|
|
28
44
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
45
|
+
context "with ActiveRecord above or equal to 5.2.0", skip: ActiveRecord.version < Gem::Version.new("5.2.0") do
|
|
46
|
+
before do
|
|
47
|
+
allow(Apartment::Migrator).to receive(:activerecord_below_5_2?) { false }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
describe "::migrate" do
|
|
51
|
+
it "switches and migrates" do
|
|
52
|
+
expect(Apartment::Tenant).to receive(:switch).with(tenant).and_call_original
|
|
53
|
+
expect_any_instance_of(ActiveRecord::MigrationContext).to receive(:migrate)
|
|
54
|
+
|
|
55
|
+
Apartment::Migrator.migrate(tenant)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
describe "::run" do
|
|
60
|
+
it "switches and runs" do
|
|
61
|
+
expect(Apartment::Tenant).to receive(:switch).with(tenant).and_call_original
|
|
62
|
+
expect_any_instance_of(ActiveRecord::MigrationContext).to receive(:run).with(:up, 1234)
|
|
63
|
+
|
|
64
|
+
Apartment::Migrator.run(:up, tenant, 1234)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
describe "::rollback" do
|
|
69
|
+
it "switches and rolls back" do
|
|
70
|
+
expect(Apartment::Tenant).to receive(:switch).with(tenant).and_call_original
|
|
71
|
+
expect_any_instance_of(ActiveRecord::MigrationContext).to receive(:rollback).with(2)
|
|
33
72
|
|
|
34
|
-
|
|
73
|
+
Apartment::Migrator.rollback(tenant, 2)
|
|
74
|
+
end
|
|
35
75
|
end
|
|
36
76
|
end
|
|
37
77
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: apartment
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ryan Brunner
|
|
@@ -9,7 +9,7 @@ authors:
|
|
|
9
9
|
autorequire:
|
|
10
10
|
bindir: bin
|
|
11
11
|
cert_chain: []
|
|
12
|
-
date:
|
|
12
|
+
date: 2018-04-13 00:00:00.000000000 Z
|
|
13
13
|
dependencies:
|
|
14
14
|
- !ruby/object:Gem::Dependency
|
|
15
15
|
name: activerecord
|
|
@@ -147,30 +147,30 @@ dependencies:
|
|
|
147
147
|
name: mysql2
|
|
148
148
|
requirement: !ruby/object:Gem::Requirement
|
|
149
149
|
requirements:
|
|
150
|
-
- - "
|
|
150
|
+
- - ">="
|
|
151
151
|
- !ruby/object:Gem::Version
|
|
152
|
-
version: 0
|
|
152
|
+
version: '0'
|
|
153
153
|
type: :development
|
|
154
154
|
prerelease: false
|
|
155
155
|
version_requirements: !ruby/object:Gem::Requirement
|
|
156
156
|
requirements:
|
|
157
|
-
- - "
|
|
157
|
+
- - ">="
|
|
158
158
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: 0
|
|
159
|
+
version: '0'
|
|
160
160
|
- !ruby/object:Gem::Dependency
|
|
161
161
|
name: pg
|
|
162
162
|
requirement: !ruby/object:Gem::Requirement
|
|
163
163
|
requirements:
|
|
164
164
|
- - ">="
|
|
165
165
|
- !ruby/object:Gem::Version
|
|
166
|
-
version: 0
|
|
166
|
+
version: '0'
|
|
167
167
|
type: :development
|
|
168
168
|
prerelease: false
|
|
169
169
|
version_requirements: !ruby/object:Gem::Requirement
|
|
170
170
|
requirements:
|
|
171
171
|
- - ">="
|
|
172
172
|
- !ruby/object:Gem::Version
|
|
173
|
-
version: 0
|
|
173
|
+
version: '0'
|
|
174
174
|
- !ruby/object:Gem::Dependency
|
|
175
175
|
name: sqlite3
|
|
176
176
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -208,11 +208,10 @@ files:
|
|
|
208
208
|
- TODO.md
|
|
209
209
|
- apartment.gemspec
|
|
210
210
|
- docker-compose.yml
|
|
211
|
-
- gemfiles/rails_4_0.gemfile
|
|
212
|
-
- gemfiles/rails_4_1.gemfile
|
|
213
211
|
- gemfiles/rails_4_2.gemfile
|
|
214
212
|
- gemfiles/rails_5_0.gemfile
|
|
215
213
|
- gemfiles/rails_5_1.gemfile
|
|
214
|
+
- gemfiles/rails_5_2.gemfile
|
|
216
215
|
- gemfiles/rails_master.gemfile
|
|
217
216
|
- lib/apartment.rb
|
|
218
217
|
- lib/apartment/adapters/abstract_adapter.rb
|
|
@@ -360,7 +359,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
360
359
|
version: '0'
|
|
361
360
|
requirements: []
|
|
362
361
|
rubyforge_project:
|
|
363
|
-
rubygems_version: 2.
|
|
362
|
+
rubygems_version: 2.7.6
|
|
364
363
|
signing_key:
|
|
365
364
|
specification_version: 4
|
|
366
365
|
summary: A Ruby gem for managing database multitenancy
|
data/gemfiles/rails_4_0.gemfile
DELETED