tenant_realm 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ec5080c5a6b4e997fd094811df564e8cb6c7520030a1fb0617917a155dd05223
4
- data.tar.gz: 159100e048f540997d9e9ffa33ba215c035357573bb297a65afa52bd6547d593
3
+ metadata.gz: cb38988c0c6f15c4ab3ad38292bf08b4f1f3f30579d4c50b6fe992748f9c4c53
4
+ data.tar.gz: '0740480bc624fbd480c00dee419d442b3358093b12b5a080787cba77898708b7'
5
5
  SHA512:
6
- metadata.gz: 789611a5e9bc41b794a65e39d4d4cb48a69ad6d37a6d1bde72cb10e6f2bf499278f6715c5f50a7ba26023360408919bf921e33e72b9b994263747582eb0e8dc8
7
- data.tar.gz: a7dc2cddb27f123a9772bd53d4e4b1f3d39f9f5cad245f83de9329aa9c3bd6acebde917cb42ce84927b12b896396f8837fe715f5f22ede2cbcec365cb2d72bfc
6
+ metadata.gz: 2babc4881ad94fbd81ae8356de99ea1ba9b3cd970ac78ef5a3ccbde642c5cedffa5560b36a0e27cb88eed3d3b30f4300d21811edce64cb4149abf7070cbf64ac
7
+ data.tar.gz: a0fd3f716507576ba08520997faeb93f6748c383c523e96266ec5fd7c9969e36e66e948cf39630d8caa09642ac36ccaf6e8fbab52b4bb5c474f012885925e75c
@@ -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(_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(_tenant)
15
+ def cache_tenant(tenant:)
16
16
  raise NotImplementedError
17
17
  end
18
18
 
19
- def tenant(_identifier)
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 << ActiveRecord::DatabaseConfigurations::HashConfig.new(
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
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # internal usage
4
+ # no need hash parameters
3
5
  module TenantRealm
4
6
  class Helpers
5
7
  class << self
@@ -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
- tenants = cache.tenants
16
- return tenants if tenants.present?
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
- tenant = cache.tenant(identifier)
29
- return tenant if tenant.present?
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
@@ -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')
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TenantRealm
4
- VERSION = '1.0.0'
4
+ VERSION = '1.1.0'
5
5
  end
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
@@ -34,6 +34,10 @@ Gem::Specification.new do |spec|
34
34
  .vscode/settings.json
35
35
  LICENSE.txt
36
36
  lefthook.yml
37
+ docs/
38
+ biome.json
39
+ package.json
40
+ pnpm-lock.yaml
37
41
  ]
38
42
  )
39
43
  end
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.0.0
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-27 00:00:00.000000000 Z
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