apartment 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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