tenant_realm 1.0.0 → 1.1.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/lib/tasks/migrate.rake +10 -0
- data/lib/tasks/rollback.rake +29 -0
- data/lib/tenant_realm/cache/base_cache.rb +3 -3
- data/lib/tenant_realm/cache/kredis_cache.rb +5 -3
- data/lib/tenant_realm/db_context.rb +25 -3
- data/lib/tenant_realm/helpers.rb +2 -0
- data/lib/tenant_realm/tenant.rb +17 -13
- data/lib/tenant_realm/utils.rb +2 -2
- data/lib/tenant_realm/version.rb +1 -1
- data/lib/tenant_realm.rb +3 -3
- data/tenant_realm.gemspec +4 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb38988c0c6f15c4ab3ad38292bf08b4f1f3f30579d4c50b6fe992748f9c4c53
|
4
|
+
data.tar.gz: '0740480bc624fbd480c00dee419d442b3358093b12b5a080787cba77898708b7'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2babc4881ad94fbd81ae8356de99ea1ba9b3cd970ac78ef5a3ccbde642c5cedffa5560b36a0e27cb88eed3d3b30f4300d21811edce64cb4149abf7070cbf64ac
|
7
|
+
data.tar.gz: a0fd3f716507576ba08520997faeb93f6748c383c523e96266ec5fd7c9969e36e66e948cf39630d8caa09642ac36ccaf6e8fbab52b4bb5c474f012885925e75c
|
data/lib/tasks/migrate.rake
CHANGED
@@ -5,6 +5,16 @@ namespace :tenant_realm do
|
|
5
5
|
task migrate: :environment do
|
6
6
|
tenants = TenantRealm::Tenant.tenants
|
7
7
|
|
8
|
+
puts 'Migrating primary'
|
9
|
+
root_db_config = TenantRealm::DbContext.root_db_config
|
10
|
+
ActiveRecord::Tasks::DatabaseTasks.with_temporary_connection(root_db_config) do
|
11
|
+
ActiveRecord::Tasks::DatabaseTasks.migrate
|
12
|
+
TenantRealm::DbContext.dump_schema(
|
13
|
+
shard: :primary,
|
14
|
+
db_config: root_db_config
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
8
18
|
tenants.each do |tenant|
|
9
19
|
shard = TenantRealm::Utils.shard_name_from_tenant(tenant:)
|
10
20
|
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :tenant_realm do
|
4
|
+
desc 'Rollback db for all tenants'
|
5
|
+
task rollback: :environment do
|
6
|
+
tenants = TenantRealm::Tenant.tenants
|
7
|
+
|
8
|
+
puts 'Rollback primary'
|
9
|
+
Rake::Task['db:rollback:primary'].invoke
|
10
|
+
Rake::Task['db:rollback:primary'].reenable
|
11
|
+
|
12
|
+
tenants.each do |tenant|
|
13
|
+
shard = TenantRealm::Utils.shard_name_from_tenant(tenant:)
|
14
|
+
|
15
|
+
puts "Rollback #{shard}"
|
16
|
+
|
17
|
+
db_config = TenantRealm::Utils.dig_db_config(tenant:)
|
18
|
+
|
19
|
+
if db_config.blank?
|
20
|
+
puts "Skip Rollback #{shard}"
|
21
|
+
|
22
|
+
next
|
23
|
+
end
|
24
|
+
|
25
|
+
Rake::Task["db:rollback:#{shard}"].invoke
|
26
|
+
Rake::Task["db:rollback:#{shard}"].reenable
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -4,7 +4,7 @@ module TenantRealm
|
|
4
4
|
module Cache
|
5
5
|
class BaseCache
|
6
6
|
class << self
|
7
|
-
def cache_tenants(
|
7
|
+
def cache_tenants(tenants:)
|
8
8
|
raise NotImplementedError
|
9
9
|
end
|
10
10
|
|
@@ -12,11 +12,11 @@ module TenantRealm
|
|
12
12
|
raise NotImplementedError
|
13
13
|
end
|
14
14
|
|
15
|
-
def cache_tenant(
|
15
|
+
def cache_tenant(tenant:)
|
16
16
|
raise NotImplementedError
|
17
17
|
end
|
18
18
|
|
19
|
-
def tenant(
|
19
|
+
def tenant(identifier:)
|
20
20
|
raise NotImplementedError
|
21
21
|
end
|
22
22
|
|
@@ -9,7 +9,7 @@ module TenantRealm
|
|
9
9
|
module Cache
|
10
10
|
class KredisCache < BaseCache
|
11
11
|
class << self
|
12
|
-
def cache_tenants(tenants)
|
12
|
+
def cache_tenants(tenants:)
|
13
13
|
return if tenants.blank?
|
14
14
|
|
15
15
|
cached_tenants = tenants_kredis
|
@@ -22,7 +22,9 @@ module TenantRealm
|
|
22
22
|
cached_tenants.value&.map(&:deep_symbolize_keys) || []
|
23
23
|
end
|
24
24
|
|
25
|
-
def cache_tenant(tenant)
|
25
|
+
def cache_tenant(tenant:)
|
26
|
+
return tenant if tenant.blank?
|
27
|
+
|
26
28
|
tenant_unique_keys(tenant).each do |key|
|
27
29
|
cached_tenant = tenant_kredis(key)
|
28
30
|
cached_tenant.value = tenant
|
@@ -31,7 +33,7 @@ module TenantRealm
|
|
31
33
|
tenant
|
32
34
|
end
|
33
35
|
|
34
|
-
def tenant(identifier)
|
36
|
+
def tenant(identifier:)
|
35
37
|
cached_tenant = tenant_kredis(identifier)
|
36
38
|
cached_tenant.value&.deep_symbolize_keys
|
37
39
|
end
|
@@ -55,10 +55,10 @@ module TenantRealm
|
|
55
55
|
YAML.dump(config, f)
|
56
56
|
end
|
57
57
|
|
58
|
-
ActiveRecord::Base.configurations.configurations <<
|
59
|
-
Rails.env,
|
58
|
+
ActiveRecord::Base.configurations.configurations << build_db_hash_config(
|
60
59
|
shard_name,
|
61
|
-
tenant_shard_config
|
60
|
+
tenant_shard_config,
|
61
|
+
Rails.env
|
62
62
|
)
|
63
63
|
|
64
64
|
sym_shard = shard_name.to_sym
|
@@ -110,8 +110,30 @@ module TenantRealm
|
|
110
110
|
db_config
|
111
111
|
end
|
112
112
|
|
113
|
+
def dump_schema(db_config:, shard:)
|
114
|
+
return unless ActiveRecord.dump_schema_after_migration
|
115
|
+
|
116
|
+
schema_format = ENV.fetch('SCHEMA_FORMAT', ActiveRecord.schema_format).to_sym
|
117
|
+
ActiveRecord::Tasks::DatabaseTasks.dump_schema(
|
118
|
+
build_db_hash_config(
|
119
|
+
shard.to_s,
|
120
|
+
db_config,
|
121
|
+
Rails.env
|
122
|
+
),
|
123
|
+
schema_format
|
124
|
+
)
|
125
|
+
end
|
126
|
+
|
113
127
|
private
|
114
128
|
|
129
|
+
def build_db_hash_config(shard, db_config, env_name = Rails.env)
|
130
|
+
ActiveRecord::DatabaseConfigurations::HashConfig.new(
|
131
|
+
env_name,
|
132
|
+
shard,
|
133
|
+
db_config
|
134
|
+
)
|
135
|
+
end
|
136
|
+
|
115
137
|
def build_connected_shards
|
116
138
|
@@shards.keys.each_with_object({}) do |shard, shards|
|
117
139
|
sym_shard = shard.to_sym
|
data/lib/tenant_realm/helpers.rb
CHANGED
data/lib/tenant_realm/tenant.rb
CHANGED
@@ -10,42 +10,46 @@ module TenantRealm
|
|
10
10
|
}
|
11
11
|
|
12
12
|
class << self
|
13
|
-
def tenants
|
13
|
+
def tenants(force_load: false)
|
14
14
|
if cache.present?
|
15
|
-
|
16
|
-
|
15
|
+
unless force_load
|
16
|
+
tenants = cache.tenants
|
17
|
+
return tenants if tenants.present?
|
18
|
+
end
|
17
19
|
|
18
20
|
tenants = Utils.fetch_tenants
|
19
|
-
cache.cache_tenants(tenants)
|
21
|
+
cache.cache_tenants(tenants:)
|
20
22
|
tenants
|
21
23
|
else
|
22
24
|
Utils.fetch_tenants
|
23
25
|
end
|
24
26
|
end
|
25
27
|
|
26
|
-
def tenant(identifier)
|
28
|
+
def tenant(identifier:, force_load: false)
|
27
29
|
if cache.present?
|
28
|
-
|
29
|
-
|
30
|
+
unless force_load
|
31
|
+
tenant = cache.tenant(identifier:)
|
32
|
+
return tenant if tenant.present?
|
33
|
+
end
|
30
34
|
|
31
|
-
tenant = Utils.fetch_tenant(identifier)
|
32
|
-
cache.cache_tenant(tenant)
|
35
|
+
tenant = Utils.fetch_tenant(identifier:)
|
36
|
+
cache.cache_tenant(tenant:)
|
33
37
|
tenant
|
34
38
|
else
|
35
39
|
Utils.fetch_tenant
|
36
40
|
end
|
37
41
|
end
|
38
42
|
|
39
|
-
def cache_tenants(tenants)
|
43
|
+
def cache_tenants(tenants:)
|
40
44
|
return Helpers.dev_log('Tenant Realm: Skip cache tenants because cache not configured') if cache.blank?
|
41
45
|
|
42
|
-
cache.cache_tenants(tenants)
|
46
|
+
cache.cache_tenants(tenants:)
|
43
47
|
end
|
44
48
|
|
45
|
-
def cache_tenant(tenant)
|
49
|
+
def cache_tenant(tenant:)
|
46
50
|
return Helpers.dev_log('Tenant Realm: Skip cache tenant because cache not configured') if cache.blank?
|
47
51
|
|
48
|
-
cache.cache_tenant(tenant)
|
52
|
+
cache.cache_tenant(tenant:)
|
49
53
|
end
|
50
54
|
|
51
55
|
private
|
data/lib/tenant_realm/utils.rb
CHANGED
@@ -13,7 +13,7 @@ module TenantRealm
|
|
13
13
|
(Config.fetch_tenants.call.presence || []).map(&:deep_symbolize_keys)
|
14
14
|
end
|
15
15
|
|
16
|
-
def fetch_tenant(identifier)
|
16
|
+
def fetch_tenant(identifier:)
|
17
17
|
Helpers.raise_if_not_proc(Config.fetch_tenant, 'config.fetch_tenant')
|
18
18
|
|
19
19
|
Config.fetch_tenant.call(identifier)&.deep_symbolize_keys
|
@@ -41,7 +41,7 @@ module TenantRealm
|
|
41
41
|
shard.underscore
|
42
42
|
end
|
43
43
|
|
44
|
-
def identifier_resolver(request)
|
44
|
+
def identifier_resolver(request:)
|
45
45
|
raise Error, 'config.identifier_resolver must be provided' if Config.identifier_resolver.blank?
|
46
46
|
|
47
47
|
Helpers.raise_if_not_proc(Config.identifier_resolver, 'config.identifier_resolver')
|
data/lib/tenant_realm/version.rb
CHANGED
data/lib/tenant_realm.rb
CHANGED
@@ -30,13 +30,13 @@ module TenantRealm
|
|
30
30
|
|
31
31
|
return :primary if skip_switch_db
|
32
32
|
|
33
|
-
identifier = Utils.identifier_resolver(request)
|
34
|
-
tenant = Tenant.tenant(identifier)
|
33
|
+
identifier = Utils.identifier_resolver(request:)
|
34
|
+
tenant = Tenant.tenant(identifier:)
|
35
35
|
db_config = Utils.dig_db_config(tenant:)
|
36
|
-
shard = Utils.shard_name_from_tenant(tenant:)
|
37
36
|
|
38
37
|
return :primary if db_config.blank?
|
39
38
|
|
39
|
+
shard = Utils.shard_name_from_tenant(tenant:)
|
40
40
|
Config.current.tenant = tenant
|
41
41
|
DbContext.add_shard(shard:, db_config:)
|
42
42
|
ActiveRecord::Base.connects_to(shards: DbContext.connected_shards)
|
data/tenant_realm.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tenant_realm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alpha
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-01-
|
11
|
+
date: 2024-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby on Rails gem to support multi-tenant
|
14
14
|
email:
|
@@ -23,6 +23,7 @@ files:
|
|
23
23
|
- lib/generators/templates/tenant_realm.tt
|
24
24
|
- lib/generators/tenant_realm_generator.rb
|
25
25
|
- lib/tasks/migrate.rake
|
26
|
+
- lib/tasks/rollback.rake
|
26
27
|
- lib/tenant_realm.rb
|
27
28
|
- lib/tenant_realm/cache/base_cache.rb
|
28
29
|
- lib/tenant_realm/cache/kredis_cache.rb
|