ros-apartment 3.0.4 → 3.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 +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/adapters/trilogy_adapter.rb +29 -0
- 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 -34
- metadata +36 -233
- data/.rubocop_todo.yml +0 -436
- /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
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'apartment/adapters/mysql2_adapter'
|
4
|
+
|
5
|
+
module Apartment
|
6
|
+
# Helper module to decide wether to use trilogy adapter or trilogy adapter with schemas
|
7
|
+
module Tenant
|
8
|
+
def self.trilogy_adapter(config)
|
9
|
+
if Apartment.use_schemas
|
10
|
+
Adapters::TrilogySchemaAdapter.new(config)
|
11
|
+
else
|
12
|
+
Adapters::TrilogyAdapter.new(config)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Adapters
|
18
|
+
class TrilogyAdapter < Mysql2Adapter
|
19
|
+
protected
|
20
|
+
|
21
|
+
def rescue_from
|
22
|
+
Trilogy::Error
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
class TrilogySchemaAdapter < Mysql2SchemaAdapter
|
27
|
+
end
|
28
|
+
end
|
29
|
+
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,44 +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
|
-
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')
|
64
40
|
end
|