activerecord-tenanted 0.4.1 → 0.5.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/active_record/tenanted/database_adapter.rb +25 -0
- data/lib/active_record/tenanted/database_adapters/sqlite.rb +115 -0
- data/lib/active_record/tenanted/database_configurations/base_config.rb +10 -49
- data/lib/active_record/tenanted/database_configurations/tenant_config.rb +13 -15
- data/lib/active_record/tenanted/database_tasks.rb +12 -16
- data/lib/active_record/tenanted/tenant.rb +16 -23
- data/lib/active_record/tenanted/version.rb +1 -1
- data/lib/active_record/tenanted.rb +6 -0
- data/lib/tasks/active_record/tenanted_tasks.rake +2 -2
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: e6045a554346528724708d7acfcefa45c3445f5dd1bbc184426ce13e995bbb83
|
|
4
|
+
data.tar.gz: 5c752644fcb587efff882e8c117933147dccc5771e74c3ea3d9b967eaa33f5dc
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: cb160898373d824906708a959d59b40d1f76fa398b2fcdebadd57b590ddd63a3da2fcbe53eb8787a5af041f108eb27516afb27febe4aa62eb76c9a1cd7cccd4f
|
|
7
|
+
data.tar.gz: e001ccf67a7e4891df031ee6ceb34c20f227cb3ef3499decf2e5cce59b638a76f9a8b4200c55105910a74c3f7478c11b32aeb34d8f7da481d8b388a51997b899
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveRecord
|
|
4
|
+
module Tenanted
|
|
5
|
+
class DatabaseAdapter # :nodoc:
|
|
6
|
+
ADAPTERS = {
|
|
7
|
+
"sqlite3" => "ActiveRecord::Tenanted::DatabaseAdapters::SQLite",
|
|
8
|
+
}.freeze
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
def new(db_config)
|
|
12
|
+
adapter_class_name = ADAPTERS[db_config.adapter]
|
|
13
|
+
|
|
14
|
+
if adapter_class_name.nil?
|
|
15
|
+
raise ActiveRecord::Tenanted::UnsupportedDatabaseError,
|
|
16
|
+
"Unsupported database adapter for tenanting: #{db_config.adapter}. " \
|
|
17
|
+
"Supported adapters: #{ADAPTERS.keys.join(', ')}"
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
adapter_class_name.constantize.new(db_config)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ActiveRecord
|
|
4
|
+
module Tenanted
|
|
5
|
+
module DatabaseAdapters # :nodoc:
|
|
6
|
+
#
|
|
7
|
+
# TODO: This still feels to me like it's not _quite_ right. I think we could further refactor this by:
|
|
8
|
+
#
|
|
9
|
+
# 1. Moving tenant_databases and validate_tenant_name to BaseConfig, and subclassing it for
|
|
10
|
+
# each database
|
|
11
|
+
# 2. Moving create_database, drop_database, database_exist?, database_ready?,
|
|
12
|
+
# acquire_ready_lock, ensure_database_directory_exists, and database_path to the SQLite
|
|
13
|
+
# connection adapter, possibly into Rails
|
|
14
|
+
# 3. Moving test_workerize and path_for to be SQLite connection adapter class methods,
|
|
15
|
+
# possibly into Rails
|
|
16
|
+
#
|
|
17
|
+
class SQLite
|
|
18
|
+
attr_reader :db_config
|
|
19
|
+
|
|
20
|
+
def initialize(db_config)
|
|
21
|
+
@db_config = db_config
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def tenant_databases
|
|
25
|
+
glob = path_for(db_config.database_for("*"))
|
|
26
|
+
scanner = Regexp.new(path_for(db_config.database_for("(.+)")))
|
|
27
|
+
|
|
28
|
+
Dir.glob(glob).filter_map do |path|
|
|
29
|
+
result = path.scan(scanner).flatten.first
|
|
30
|
+
if result.nil?
|
|
31
|
+
Rails.logger.warn "ActiveRecord::Tenanted: Cannot parse tenant name from filename #{path.inspect}"
|
|
32
|
+
end
|
|
33
|
+
result
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def validate_tenant_name(tenant_name)
|
|
38
|
+
if tenant_name.match?(%r{[/'"`]})
|
|
39
|
+
raise BadTenantNameError, "Tenant name contains an invalid character: #{tenant_name.inspect}"
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def create_database
|
|
44
|
+
ensure_database_directory_exists
|
|
45
|
+
FileUtils.touch(database_path)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def drop_database
|
|
49
|
+
# Remove the SQLite database file and associated files
|
|
50
|
+
FileUtils.rm_f(database_path)
|
|
51
|
+
FileUtils.rm_f("#{database_path}-wal") # Write-Ahead Logging file
|
|
52
|
+
FileUtils.rm_f("#{database_path}-shm") # Shared Memory file
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def database_exist?
|
|
56
|
+
File.exist?(database_path)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def database_ready?
|
|
60
|
+
File.exist?(database_path) && !ActiveRecord::Tenanted::Mutex::Ready.locked?(database_path)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def acquire_ready_lock(&block)
|
|
64
|
+
ActiveRecord::Tenanted::Mutex::Ready.lock(database_path, &block)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def ensure_database_directory_exists
|
|
68
|
+
return unless database_path
|
|
69
|
+
|
|
70
|
+
database_dir = File.dirname(database_path)
|
|
71
|
+
unless File.directory?(database_dir)
|
|
72
|
+
FileUtils.mkdir_p(database_dir)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def database_path
|
|
77
|
+
path_for(db_config.database)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def test_workerize(db, test_worker_id)
|
|
81
|
+
test_worker_suffix = "_#{test_worker_id}"
|
|
82
|
+
|
|
83
|
+
if db.start_with?("file:") && db.include?("?")
|
|
84
|
+
db.sub(/(\?.*)$/, "#{test_worker_suffix}\\1")
|
|
85
|
+
else
|
|
86
|
+
# This check is needed because of https://github.com/rails/rails/pull/55769 adding
|
|
87
|
+
# replicas to the parallelization setup by using `include_hidden: true` which pulls in
|
|
88
|
+
# the BaseConfig. We don't want to double-suffix the database name.
|
|
89
|
+
#
|
|
90
|
+
# TODO: Ideally we should have finer-grained filtering of database configurations in Rails
|
|
91
|
+
# (other than simply hidden or not-hidden).
|
|
92
|
+
if db.end_with?(test_worker_suffix)
|
|
93
|
+
db
|
|
94
|
+
else
|
|
95
|
+
db + test_worker_suffix
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# A sqlite database path can be a file path or a URI (either relative or absolute). We
|
|
101
|
+
# can't parse it as a standard URI in all circumstances, though, see
|
|
102
|
+
# https://sqlite.org/uri.html
|
|
103
|
+
def path_for(database)
|
|
104
|
+
if database.start_with?("file:/")
|
|
105
|
+
URI.parse(database).path
|
|
106
|
+
elsif database.start_with?("file:")
|
|
107
|
+
URI.parse(database.sub(/\?.*$/, "")).opaque
|
|
108
|
+
else
|
|
109
|
+
database
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
@@ -11,6 +11,11 @@ module ActiveRecord
|
|
|
11
11
|
def initialize(...)
|
|
12
12
|
super
|
|
13
13
|
@test_worker_id = nil
|
|
14
|
+
@config_adapter = nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def config_adapter
|
|
18
|
+
@config_adapter ||= ActiveRecord::Tenanted::DatabaseAdapter.new(self)
|
|
14
19
|
end
|
|
15
20
|
|
|
16
21
|
def database_tasks?
|
|
@@ -20,33 +25,19 @@ module ActiveRecord
|
|
|
20
25
|
def database_for(tenant_name)
|
|
21
26
|
tenant_name = tenant_name.to_s
|
|
22
27
|
|
|
23
|
-
validate_tenant_name(tenant_name)
|
|
28
|
+
config_adapter.validate_tenant_name(tenant_name)
|
|
24
29
|
|
|
25
|
-
|
|
30
|
+
db = sprintf(database, tenant: tenant_name)
|
|
26
31
|
|
|
27
32
|
if test_worker_id
|
|
28
|
-
|
|
29
|
-
else
|
|
30
|
-
path
|
|
33
|
+
db = config_adapter.test_workerize(db, test_worker_id)
|
|
31
34
|
end
|
|
32
|
-
end
|
|
33
35
|
|
|
34
|
-
|
|
35
|
-
coerce_path(database_for(tenant_name))
|
|
36
|
+
db
|
|
36
37
|
end
|
|
37
38
|
|
|
38
39
|
def tenants
|
|
39
|
-
|
|
40
|
-
scanner = Regexp.new(database_path_for("(.+)"))
|
|
41
|
-
|
|
42
|
-
Dir.glob(glob).map do |path|
|
|
43
|
-
result = path.scan(scanner).flatten.first
|
|
44
|
-
if result.nil?
|
|
45
|
-
warn "WARN: ActiveRecord::Tenanted: Cannot parse tenant name from filename #{path.inspect}. " \
|
|
46
|
-
"This is a bug, please report it to https://github.com/basecamp/activerecord-tenanted/issues"
|
|
47
|
-
end
|
|
48
|
-
result
|
|
49
|
-
end
|
|
40
|
+
config_adapter.tenant_databases
|
|
50
41
|
end
|
|
51
42
|
|
|
52
43
|
def new_tenant_config(tenant_name)
|
|
@@ -54,7 +45,6 @@ module ActiveRecord
|
|
|
54
45
|
config_hash = configuration_hash.dup.tap do |hash|
|
|
55
46
|
hash[:tenant] = tenant_name
|
|
56
47
|
hash[:database] = database_for(tenant_name)
|
|
57
|
-
hash[:database_path] = database_path_for(tenant_name)
|
|
58
48
|
hash[:tenanted_config_name] = name
|
|
59
49
|
end
|
|
60
50
|
Tenanted::DatabaseConfigurations::TenantConfig.new(env_name, config_name, config_hash)
|
|
@@ -70,35 +60,6 @@ module ActiveRecord
|
|
|
70
60
|
def max_connection_pools
|
|
71
61
|
(configuration_hash[:max_connection_pools] || DEFAULT_MAX_CONNECTION_POOLS).to_i
|
|
72
62
|
end
|
|
73
|
-
|
|
74
|
-
private
|
|
75
|
-
# A sqlite database path can be a file path or a URI (either relative or absolute).
|
|
76
|
-
# We can't parse it as a standard URI in all circumstances, though, see https://sqlite.org/uri.html
|
|
77
|
-
def coerce_path(path)
|
|
78
|
-
if path.start_with?("file:/")
|
|
79
|
-
URI.parse(path).path
|
|
80
|
-
elsif path.start_with?("file:")
|
|
81
|
-
URI.parse(path.sub(/\?.*$/, "")).opaque
|
|
82
|
-
else
|
|
83
|
-
path
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def validate_tenant_name(tenant_name)
|
|
88
|
-
if tenant_name.match?(%r{[/'"`]})
|
|
89
|
-
raise BadTenantNameError, "Tenant name contains an invalid character: #{tenant_name.inspect}"
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def test_worker_path(path)
|
|
94
|
-
test_worker_suffix = "_#{test_worker_id}"
|
|
95
|
-
|
|
96
|
-
if path.start_with?("file:") && path.include?("?")
|
|
97
|
-
path.sub(/(\?.*)$/, "#{test_worker_suffix}\\1")
|
|
98
|
-
else
|
|
99
|
-
path + test_worker_suffix
|
|
100
|
-
end
|
|
101
|
-
end
|
|
102
63
|
end
|
|
103
64
|
end
|
|
104
65
|
end
|
|
@@ -4,12 +4,24 @@ module ActiveRecord
|
|
|
4
4
|
module Tenanted
|
|
5
5
|
module DatabaseConfigurations
|
|
6
6
|
class TenantConfig < ActiveRecord::DatabaseConfigurations::HashConfig
|
|
7
|
+
def initialize(...)
|
|
8
|
+
super
|
|
9
|
+
@config_adapter = nil
|
|
10
|
+
end
|
|
11
|
+
|
|
7
12
|
def tenant
|
|
8
13
|
configuration_hash.fetch(:tenant)
|
|
9
14
|
end
|
|
10
15
|
|
|
16
|
+
def config_adapter
|
|
17
|
+
@config_adapter ||= ActiveRecord::Tenanted::DatabaseAdapter.new(self)
|
|
18
|
+
end
|
|
19
|
+
|
|
11
20
|
def new_connection
|
|
12
|
-
|
|
21
|
+
# TODO: The Rails SQLite adapter doesn't handle directory creation for file: URIs. I would
|
|
22
|
+
# like to fix that upstream, and remove this line.
|
|
23
|
+
config_adapter.ensure_database_directory_exists
|
|
24
|
+
|
|
13
25
|
super.tap { |conn| conn.tenant = tenant }
|
|
14
26
|
end
|
|
15
27
|
|
|
@@ -36,20 +48,6 @@ module ActiveRecord
|
|
|
36
48
|
File.join(db_dir, "#{tenanted_config_name}_schema_cache.yml")
|
|
37
49
|
end
|
|
38
50
|
end
|
|
39
|
-
|
|
40
|
-
def database_path
|
|
41
|
-
configuration_hash[:database_path]
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
private
|
|
45
|
-
def ensure_database_directory_exists
|
|
46
|
-
return unless database_path
|
|
47
|
-
|
|
48
|
-
database_dir = File.dirname(database_path)
|
|
49
|
-
unless File.directory?(database_dir)
|
|
50
|
-
FileUtils.mkdir_p(database_dir)
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
51
|
end
|
|
54
52
|
end
|
|
55
53
|
end
|
|
@@ -6,38 +6,34 @@ module ActiveRecord
|
|
|
6
6
|
extend self
|
|
7
7
|
|
|
8
8
|
def migrate_all
|
|
9
|
-
raise ArgumentError, "Could not find a tenanted database" unless
|
|
9
|
+
raise ArgumentError, "Could not find a tenanted database" unless config = base_config
|
|
10
10
|
|
|
11
|
-
tenants =
|
|
11
|
+
tenants = config.tenants.presence || [ get_current_tenant ].compact
|
|
12
12
|
tenants.each do |tenant|
|
|
13
|
-
tenant_config =
|
|
13
|
+
tenant_config = config.new_tenant_config(tenant)
|
|
14
14
|
migrate(tenant_config)
|
|
15
15
|
end
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
def migrate_tenant(tenant_name = set_current_tenant)
|
|
19
|
-
raise ArgumentError, "Could not find a tenanted database" unless
|
|
19
|
+
raise ArgumentError, "Could not find a tenanted database" unless config = base_config
|
|
20
20
|
|
|
21
|
-
tenant_config =
|
|
21
|
+
tenant_config = config.new_tenant_config(tenant_name)
|
|
22
22
|
|
|
23
23
|
migrate(tenant_config)
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def drop_all
|
|
27
|
-
raise ArgumentError, "Could not find a tenanted database" unless
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
root_config.database_path_for(tenant).tap do |path|
|
|
34
|
-
FileUtils.rm(path)
|
|
35
|
-
$stdout.puts "Dropped database '#{path}'" if verbose?
|
|
36
|
-
end
|
|
27
|
+
raise ArgumentError, "Could not find a tenanted database" unless config = base_config
|
|
28
|
+
|
|
29
|
+
config.tenants.each do |tenant|
|
|
30
|
+
db_config = config.new_tenant_config(tenant)
|
|
31
|
+
db_config.config_adapter.drop_database
|
|
32
|
+
$stdout.puts "Dropped database '#{db_config.database}'" if verbose?
|
|
37
33
|
end
|
|
38
34
|
end
|
|
39
35
|
|
|
40
|
-
def
|
|
36
|
+
def base_config
|
|
41
37
|
db_configs = ActiveRecord::Base.configurations.configs_for(
|
|
42
38
|
env_name: ActiveRecord::Tasks::DatabaseTasks.env,
|
|
43
39
|
include_hidden: true
|
|
@@ -13,11 +13,13 @@ module ActiveRecord
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
def cache_key
|
|
16
|
-
tenant ? "#{
|
|
16
|
+
tenant ? "#{tenant}/#{super}" : super
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def inspect
|
|
20
|
-
|
|
20
|
+
return super unless tenant
|
|
21
|
+
|
|
22
|
+
super.sub(/\A#<\S+ /, "\\0tenant: #{tenant.inspect}, ")
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
def to_global_id(options = {})
|
|
@@ -99,10 +101,7 @@ module ActiveRecord
|
|
|
99
101
|
end
|
|
100
102
|
|
|
101
103
|
def tenant_exist?(tenant_name)
|
|
102
|
-
|
|
103
|
-
database_path = tenanted_root_config.database_path_for(tenant_name)
|
|
104
|
-
|
|
105
|
-
File.exist?(database_path) && !ActiveRecord::Tenanted::Mutex::Ready.locked?(database_path)
|
|
104
|
+
tenanted_root_config.new_tenant_config(tenant_name).config_adapter.database_ready?
|
|
106
105
|
end
|
|
107
106
|
|
|
108
107
|
def with_tenant(tenant_name, prohibit_shard_swapping: true, &block)
|
|
@@ -121,14 +120,11 @@ module ActiveRecord
|
|
|
121
120
|
|
|
122
121
|
def create_tenant(tenant_name, if_not_exists: false, &block)
|
|
123
122
|
created_db = false
|
|
124
|
-
|
|
123
|
+
adapter = tenanted_root_config.new_tenant_config(tenant_name).config_adapter
|
|
125
124
|
|
|
126
|
-
|
|
127
|
-
unless
|
|
128
|
-
|
|
129
|
-
# TODO: Add a `create_database` method upstream in the sqlite3 adapter, and call it.
|
|
130
|
-
# Then this would delegate to the adapter and become adapter-agnostic.
|
|
131
|
-
FileUtils.touch(database_path)
|
|
125
|
+
adapter.acquire_ready_lock do
|
|
126
|
+
unless adapter.database_exist?
|
|
127
|
+
adapter.create_database
|
|
132
128
|
|
|
133
129
|
with_tenant(tenant_name) do
|
|
134
130
|
connection_pool(schema_version_check: false)
|
|
@@ -138,7 +134,7 @@ module ActiveRecord
|
|
|
138
134
|
created_db = true
|
|
139
135
|
end
|
|
140
136
|
rescue
|
|
141
|
-
|
|
137
|
+
adapter.drop_database
|
|
142
138
|
raise
|
|
143
139
|
end
|
|
144
140
|
|
|
@@ -158,10 +154,7 @@ module ActiveRecord
|
|
|
158
154
|
end
|
|
159
155
|
end
|
|
160
156
|
|
|
161
|
-
|
|
162
|
-
# TODO: Create a `drop_database` method upstream in the sqlite3 adapter, and call it.
|
|
163
|
-
# Then this would delegate to the adapter and become adapter-agnostic.
|
|
164
|
-
FileUtils.rm_f(tenanted_root_config.database_path_for(tenant_name))
|
|
157
|
+
tenanted_root_config.new_tenant_config(tenant_name).config_adapter.drop_database
|
|
165
158
|
end
|
|
166
159
|
|
|
167
160
|
def tenants
|
|
@@ -211,12 +204,12 @@ module ActiveRecord
|
|
|
211
204
|
return superclass._create_tenanted_pool unless connection_class?
|
|
212
205
|
|
|
213
206
|
tenant = current_tenant
|
|
214
|
-
|
|
215
|
-
raise TenantDoesNotExistError, "The database file for tenant #{tenant.inspect} does not exist."
|
|
216
|
-
end
|
|
207
|
+
db_config = tenanted_root_config.new_tenant_config(tenant)
|
|
217
208
|
|
|
218
|
-
|
|
219
|
-
|
|
209
|
+
unless db_config.config_adapter.database_exist?
|
|
210
|
+
raise TenantDoesNotExistError, "The database for tenant #{tenant.inspect} does not exist."
|
|
211
|
+
end
|
|
212
|
+
pool = establish_connection(db_config)
|
|
220
213
|
|
|
221
214
|
if schema_version_check
|
|
222
215
|
pending_migrations = pool.migration_context.open.pending_migrations
|
|
@@ -4,6 +4,9 @@ require "active_record"
|
|
|
4
4
|
|
|
5
5
|
require "zeitwerk"
|
|
6
6
|
loader = Zeitwerk::Loader.for_gem_extension(ActiveRecord)
|
|
7
|
+
loader.inflector.inflect(
|
|
8
|
+
"sqlite" => "SQLite",
|
|
9
|
+
)
|
|
7
10
|
loader.setup
|
|
8
11
|
|
|
9
12
|
module ActiveRecord
|
|
@@ -35,6 +38,9 @@ module ActiveRecord
|
|
|
35
38
|
# Raised when the Rails integration is being invoked but has not been configured.
|
|
36
39
|
class IntegrationNotConfiguredError < Error; end
|
|
37
40
|
|
|
41
|
+
# Raised when an unsupported database adapter is used.
|
|
42
|
+
class UnsupportedDatabaseError < Error; end
|
|
43
|
+
|
|
38
44
|
def self.connection_class
|
|
39
45
|
# TODO: cache this / speed this up
|
|
40
46
|
Rails.application.config.active_record_tenanted.connection_class&.constantize
|
|
@@ -8,7 +8,7 @@ namespace :db do
|
|
|
8
8
|
next
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
unless ActiveRecord::Tenanted::DatabaseTasks.
|
|
11
|
+
unless ActiveRecord::Tenanted::DatabaseTasks.base_config
|
|
12
12
|
warn "WARNING: No tenanted database found, skipping tenanted migration"
|
|
13
13
|
else
|
|
14
14
|
begin
|
|
@@ -42,7 +42,7 @@ namespace :db do
|
|
|
42
42
|
|
|
43
43
|
desc "Drop all tenanted databases for the current environment"
|
|
44
44
|
task "drop:tenant" => "load_config" do
|
|
45
|
-
unless ActiveRecord::Tenanted::DatabaseTasks.
|
|
45
|
+
unless ActiveRecord::Tenanted::DatabaseTasks.base_config
|
|
46
46
|
warn "WARNING: No tenanted database found, skipping tenanted reset"
|
|
47
47
|
else
|
|
48
48
|
begin
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: activerecord-tenanted
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.5.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Mike Dalessio
|
|
@@ -73,6 +73,8 @@ files:
|
|
|
73
73
|
- lib/active_record/tenanted/cable_connection.rb
|
|
74
74
|
- lib/active_record/tenanted/connection_adapter.rb
|
|
75
75
|
- lib/active_record/tenanted/console.rb
|
|
76
|
+
- lib/active_record/tenanted/database_adapter.rb
|
|
77
|
+
- lib/active_record/tenanted/database_adapters/sqlite.rb
|
|
76
78
|
- lib/active_record/tenanted/database_configurations.rb
|
|
77
79
|
- lib/active_record/tenanted/database_configurations/base_config.rb
|
|
78
80
|
- lib/active_record/tenanted/database_configurations/tenant_config.rb
|