ros-apartment 3.1.0 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +52 -9
- data/.ruby-version +1 -1
- data/Appraisals +110 -30
- data/CODE_OF_CONDUCT.md +71 -0
- data/Gemfile +15 -0
- data/README.md +48 -30
- data/Rakefile +42 -24
- data/lib/apartment/active_record/connection_handling.rb +2 -2
- data/lib/apartment/active_record/postgres/schema_dumper.rb +20 -0
- data/lib/apartment/active_record/postgresql_adapter.rb +19 -4
- data/lib/apartment/adapters/abstract_adapter.rb +1 -1
- data/lib/apartment/adapters/postgresql_adapter.rb +15 -19
- data/lib/apartment/deprecation.rb +2 -5
- data/lib/apartment/migrator.rb +15 -3
- data/lib/apartment/tasks/task_helper.rb +3 -1
- data/lib/apartment/version.rb +1 -1
- data/lib/apartment.rb +8 -2
- data/ros-apartment.gemspec +10 -35
- metadata +35 -247
- data/.rubocop_todo.yml +0 -439
- /data/{CHANGELOG.md → legacy_CHANGELOG.md} +0 -0
@@ -12,23 +12,38 @@ module Apartment::PostgreSqlAdapterPatch
|
|
12
12
|
# for JDBC driver, if rescued in super_method, trim leading and trailing quotes
|
13
13
|
res.delete!('"') if defined?(JRUBY_VERSION)
|
14
14
|
|
15
|
-
schema_prefix = "#{
|
16
|
-
default_tenant_prefix = "#{Apartment::Tenant.default_tenant}."
|
15
|
+
schema_prefix = "#{sequence_schema(res)}."
|
17
16
|
|
18
17
|
# NOTE: Excluded models should always access the sequence from the default
|
19
18
|
# tenant schema
|
20
19
|
if excluded_model?(table)
|
21
|
-
|
20
|
+
default_tenant_prefix = "#{Apartment::Tenant.default_tenant}."
|
21
|
+
|
22
|
+
# Unless the res is already prefixed with the default_tenant_prefix
|
23
|
+
# we should delete the schema_prefix and add the default_tenant_prefix
|
24
|
+
unless res&.starts_with?(default_tenant_prefix)
|
25
|
+
res&.delete_prefix!(schema_prefix)
|
26
|
+
res = default_tenant_prefix + res
|
27
|
+
end
|
28
|
+
|
22
29
|
return res
|
23
30
|
end
|
24
31
|
|
25
|
-
|
32
|
+
# Delete the schema_prefix from the res if it is present
|
33
|
+
res&.delete_prefix!(schema_prefix)
|
26
34
|
|
27
35
|
res
|
28
36
|
end
|
29
37
|
|
30
38
|
private
|
31
39
|
|
40
|
+
def sequence_schema(sequence_name)
|
41
|
+
current = Apartment::Tenant.current
|
42
|
+
return current unless current.is_a?(Array)
|
43
|
+
|
44
|
+
current.find { |schema| sequence_name.starts_with?("#{schema}.") }
|
45
|
+
end
|
46
|
+
|
32
47
|
def excluded_model?(table)
|
33
48
|
Apartment.excluded_models.any? { |m| m.constantize.table_name == table }
|
34
49
|
end
|
@@ -181,7 +181,7 @@ module Apartment
|
|
181
181
|
query_cache_enabled = ActiveRecord::Base.connection.query_cache_enabled
|
182
182
|
|
183
183
|
Apartment.establish_connection multi_tenantify(tenant)
|
184
|
-
Apartment.connection.
|
184
|
+
Apartment.connection.verify! # call active? to manually check if this connection is valid
|
185
185
|
|
186
186
|
Apartment.connection.enable_query_cache! if query_cache_enabled
|
187
187
|
rescue *rescuable_exceptions => e
|
@@ -76,11 +76,6 @@ module Apartment
|
|
76
76
|
|
77
77
|
@current = tenant.is_a?(Array) ? tenant.map(&:to_s) : tenant.to_s
|
78
78
|
Apartment.connection.schema_search_path = full_search_path
|
79
|
-
|
80
|
-
# When the PostgreSQL version is < 9.3,
|
81
|
-
# there is a issue for prepared statement with changing search_path.
|
82
|
-
# https://www.postgresql.org/docs/9.3/static/sql-prepare.html
|
83
|
-
Apartment.connection.clear_cache! if postgresql_version < 90_300
|
84
79
|
rescue *rescuable_exceptions => e
|
85
80
|
raise_schema_connect_to_new(tenant, e)
|
86
81
|
end
|
@@ -151,8 +146,9 @@ module Apartment
|
|
151
146
|
/SET row_security/i, # new in postgresql 9.5
|
152
147
|
/SET idle_in_transaction_session_timeout/i, # new in postgresql 9.6
|
153
148
|
/SET default_table_access_method/i, # new in postgresql 12
|
154
|
-
/CREATE SCHEMA
|
155
|
-
/COMMENT ON SCHEMA
|
149
|
+
/CREATE SCHEMA/i,
|
150
|
+
/COMMENT ON SCHEMA/i,
|
151
|
+
/SET transaction_timeout/i, # new in postgresql 17
|
156
152
|
|
157
153
|
].freeze
|
158
154
|
|
@@ -194,15 +190,13 @@ module Apartment
|
|
194
190
|
# @return {String} raw SQL contaning only postgres schema dump
|
195
191
|
#
|
196
192
|
def pg_dump_schema
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
with_pg_env { `pg_dump -s -x -O -n #{default_tenant} #{dbname}` }
|
193
|
+
exclude_table =
|
194
|
+
if Apartment.pg_exclude_clone_tables
|
195
|
+
excluded_tables.map! { |t| "-T #{t}" }.join(' ')
|
196
|
+
else
|
197
|
+
''
|
198
|
+
end
|
199
|
+
with_pg_env { `pg_dump -s -x -O -n #{default_tenant} #{dbname} #{exclude_table}` }
|
206
200
|
end
|
207
201
|
|
208
202
|
# Dump data from schema_migrations table
|
@@ -254,6 +248,8 @@ module Apartment
|
|
254
248
|
sql.gsub(/#{default_tenant}\.\w*/) do |match|
|
255
249
|
if Apartment.pg_excluded_names.any? { |name| match.include? name }
|
256
250
|
match
|
251
|
+
elsif Apartment.pg_exclude_clone_tables && excluded_tables.any?(match)
|
252
|
+
match
|
257
253
|
else
|
258
254
|
match.gsub("#{default_tenant}.", %("#{current}".))
|
259
255
|
end
|
@@ -266,10 +262,10 @@ module Apartment
|
|
266
262
|
regexps.select { |c| input.match c }
|
267
263
|
end
|
268
264
|
|
269
|
-
#
|
265
|
+
# Convenience method for excluded table names
|
270
266
|
#
|
271
|
-
def
|
272
|
-
|
267
|
+
def excluded_tables
|
268
|
+
Apartment.excluded_models.map do |m|
|
273
269
|
m.constantize.table_name
|
274
270
|
end
|
275
271
|
end
|
@@ -1,11 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'active_support/deprecation'
|
4
|
+
require_relative 'version'
|
4
5
|
|
5
6
|
module Apartment
|
6
|
-
|
7
|
-
def self.warn(message)
|
8
|
-
ActiveSupport::Deprecation.warn message
|
9
|
-
end
|
10
|
-
end
|
7
|
+
DEPRECATOR = ActiveSupport::Deprecation.new(Apartment::VERSION, 'Apartment')
|
11
8
|
end
|
data/lib/apartment/migrator.rb
CHANGED
@@ -13,21 +13,33 @@ module Apartment
|
|
13
13
|
|
14
14
|
migration_scope_block = ->(migration) { ENV['SCOPE'].blank? || (ENV['SCOPE'] == migration.scope) }
|
15
15
|
|
16
|
-
ActiveRecord::
|
16
|
+
if ActiveRecord.version >= Gem::Version.new('7.2.0')
|
17
|
+
ActiveRecord::Base.connection_pool.migration_context.migrate(version, &migration_scope_block)
|
18
|
+
else
|
19
|
+
ActiveRecord::Base.connection.migration_context.migrate(version, &migration_scope_block)
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
20
24
|
# Migrate up/down to a specific version
|
21
25
|
def run(direction, database, version)
|
22
26
|
Tenant.switch(database) do
|
23
|
-
ActiveRecord::
|
27
|
+
if ActiveRecord.version >= Gem::Version.new('7.2.0')
|
28
|
+
ActiveRecord::Base.connection_pool.migration_context.run(direction, version)
|
29
|
+
else
|
30
|
+
ActiveRecord::Base.connection.migration_context.run(direction, version)
|
31
|
+
end
|
24
32
|
end
|
25
33
|
end
|
26
34
|
|
27
35
|
# rollback latest migration `step` number of times
|
28
36
|
def rollback(database, step = 1)
|
29
37
|
Tenant.switch(database) do
|
30
|
-
ActiveRecord::
|
38
|
+
if ActiveRecord.version >= Gem::Version.new('7.2.0')
|
39
|
+
ActiveRecord::Base.connection_pool.migration_context.rollback(step)
|
40
|
+
else
|
41
|
+
ActiveRecord::Base.connection.migration_context.rollback(step)
|
42
|
+
end
|
31
43
|
end
|
32
44
|
end
|
33
45
|
end
|
@@ -4,7 +4,9 @@ module Apartment
|
|
4
4
|
module TaskHelper
|
5
5
|
def self.each_tenant(&block)
|
6
6
|
Parallel.each(tenants_without_default, in_threads: Apartment.parallel_migration_threads) do |tenant|
|
7
|
-
|
7
|
+
Rails.application.executor.wrap do
|
8
|
+
block.call(tenant)
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
data/lib/apartment/version.rb
CHANGED
data/lib/apartment.rb
CHANGED
@@ -5,19 +5,25 @@ require 'active_support/core_ext/object/blank'
|
|
5
5
|
require 'forwardable'
|
6
6
|
require 'active_record'
|
7
7
|
require 'apartment/tenant'
|
8
|
+
require 'apartment/deprecation'
|
8
9
|
|
9
10
|
require_relative 'apartment/log_subscriber'
|
10
11
|
require_relative 'apartment/active_record/connection_handling'
|
11
12
|
require_relative 'apartment/active_record/schema_migration'
|
12
13
|
require_relative 'apartment/active_record/internal_metadata'
|
13
14
|
|
15
|
+
if ActiveRecord.version.release >= Gem::Version.new('7.1')
|
16
|
+
require_relative 'apartment/active_record/postgres/schema_dumper'
|
17
|
+
end
|
18
|
+
|
14
19
|
# Apartment main definitions
|
15
20
|
module Apartment
|
16
21
|
class << self
|
17
22
|
extend Forwardable
|
18
23
|
|
19
24
|
ACCESSOR_METHODS = %i[use_schemas use_sql seed_after_create prepend_environment default_tenant
|
20
|
-
append_environment with_multi_server_setup tenant_presence_check
|
25
|
+
append_environment with_multi_server_setup tenant_presence_check
|
26
|
+
active_record_log pg_exclude_clone_tables].freeze
|
21
27
|
|
22
28
|
WRITER_METHODS = %i[tenant_names database_schema_file excluded_models
|
23
29
|
persistent_schemas connection_class
|
@@ -47,7 +53,7 @@ module Apartment
|
|
47
53
|
end
|
48
54
|
|
49
55
|
def tld_length=(_)
|
50
|
-
Apartment::
|
56
|
+
Apartment::DEPRECATOR.warn('`config.tld_length` have no effect because it was removed in https://github.com/influitive/apartment/pull/309')
|
51
57
|
end
|
52
58
|
|
53
59
|
def db_config_for(tenant)
|
data/ros-apartment.gemspec
CHANGED
@@ -7,10 +7,10 @@ Gem::Specification.new do |s|
|
|
7
7
|
s.name = 'ros-apartment'
|
8
8
|
s.version = Apartment::VERSION
|
9
9
|
|
10
|
-
s.authors = ['Ryan Brunner', 'Brad Robertson', 'Rui Baltazar']
|
10
|
+
s.authors = ['Ryan Brunner', 'Brad Robertson', 'Rui Baltazar', 'Mauricio Novelo']
|
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
|
-
s.email = ['ryan@influitive.com', 'brad@influitive.com', 'rui.p.baltazar@gmail.com']
|
13
|
+
s.email = ['ryan@influitive.com', 'brad@influitive.com', 'rui.p.baltazar@gmail.com', 'mauricio@campusesp.com']
|
14
14
|
# Specify which files should be added to the gem when it is released.
|
15
15
|
# The `git ls-files -z` loads the files in the RubyGem that have been
|
16
16
|
# added into git.
|
@@ -21,45 +21,20 @@ Gem::Specification.new do |s|
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
s.executables = s.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
24
|
-
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
25
24
|
s.require_paths = ['lib']
|
26
25
|
|
27
26
|
s.homepage = 'https://github.com/rails-on-services/apartment'
|
28
27
|
s.licenses = ['MIT']
|
29
28
|
s.metadata = {
|
30
|
-
'github_repo' => 'ssh://github.com/rails-on-services/apartment'
|
29
|
+
'github_repo' => 'ssh://github.com/rails-on-services/apartment',
|
30
|
+
'rubygems_mfa_required' => 'true',
|
31
31
|
}
|
32
32
|
|
33
|
-
s.required_ruby_version = '>= 3.
|
33
|
+
s.required_ruby_version = '>= 3.1'
|
34
34
|
|
35
|
-
s.add_dependency
|
36
|
-
s.add_dependency '
|
37
|
-
s.add_dependency
|
38
|
-
s.add_dependency
|
39
|
-
|
40
|
-
s.add_development_dependency 'appraisal', '~> 2.2'
|
41
|
-
s.add_development_dependency 'bundler', '>= 1.3', '< 3.0'
|
42
|
-
s.add_development_dependency 'guard-rspec', '~> 4.2'
|
43
|
-
s.add_development_dependency 'pry'
|
44
|
-
s.add_development_dependency 'rake', '~> 13.0'
|
45
|
-
s.add_development_dependency 'rspec', '~> 3.4'
|
46
|
-
s.add_development_dependency 'rspec_junit_formatter'
|
47
|
-
s.add_development_dependency 'rspec-rails', '~> 6.1'
|
48
|
-
s.add_development_dependency 'rubocop', '~> 1.63'
|
49
|
-
s.add_development_dependency 'rubocop-performance', '~> 1.21'
|
50
|
-
s.add_development_dependency 'rubocop-rails', '~> 2.24'
|
51
|
-
s.add_development_dependency 'rubocop-rspec', '~> 2.29'
|
52
|
-
|
53
|
-
if defined?(JRUBY_VERSION)
|
54
|
-
s.add_development_dependency 'activerecord-jdbc-adapter'
|
55
|
-
s.add_development_dependency 'activerecord-jdbcmysql-adapter'
|
56
|
-
s.add_development_dependency 'activerecord-jdbcpostgresql-adapter'
|
57
|
-
s.add_development_dependency 'jdbc-mysql'
|
58
|
-
s.add_development_dependency 'jdbc-postgres'
|
59
|
-
else
|
60
|
-
s.add_development_dependency 'mysql2', '~> 0.5'
|
61
|
-
s.add_development_dependency 'pg', '~> 1.5'
|
62
|
-
s.add_development_dependency 'sqlite3', '< 2.0'
|
63
|
-
s.add_development_dependency 'trilogy', '< 3.0'
|
64
|
-
end
|
35
|
+
s.add_dependency('activerecord', '>= 6.1.0', '< 8.1')
|
36
|
+
s.add_dependency('activesupport', '>= 6.1.0', '< 8.1')
|
37
|
+
s.add_dependency('parallel', '< 2.0')
|
38
|
+
s.add_dependency('public_suffix', '>= 2.0.5', '<= 6.0.1')
|
39
|
+
s.add_dependency('rack', '>= 1.3.6', '< 4.0')
|
65
40
|
end
|