rails_multisite 2.0.7 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rails_multisite might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/README.md +1 -3
- data/lib/rails_multisite/connection_management.rb +89 -23
- data/lib/rails_multisite/middleware.rb +1 -0
- data/lib/rails_multisite/railtie.rb +12 -4
- data/lib/rails_multisite/version.rb +1 -1
- data/lib/tasks/db.rake +1 -0
- data/lib/tasks/generators.rake +1 -1
- metadata +8 -8
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2acf52c9b8002bff6a1590222b85d778cb1ddd9e28de6ac91eed45d5117e30aa
|
4
|
+
data.tar.gz: 3b39a8d9a2d2b70c62e29a0541d585c499a51cb9ac6b8dac2544343b1c22d45c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f7b8775f143c21083b7141ca6592c5f8d75f12a287f14452a63ff159f0932c0fafe918256d8219431d9d3647b09b340daab747d5b0b10ff3e1c1b1c1f3eeab34
|
7
|
+
data.tar.gz: 81abf0c622d83d541bb0870a7bc2cac379c137ae4057b11a44bc8ab8ff4a6be3e1b730420766b22a55ff3aa7505ef7e9e0ab5494c8c1bdedfc8444e862cf0af0
|
data/README.md
CHANGED
@@ -35,7 +35,6 @@ mlp:
|
|
35
35
|
host: dbhost
|
36
36
|
pool: 5
|
37
37
|
timeout: 5000
|
38
|
-
db_id: 1 # ensure db_id is unique for each site
|
39
38
|
host_names:
|
40
39
|
- discourse.equestria.com
|
41
40
|
- discourse.equestria.internal
|
@@ -48,7 +47,6 @@ drwho:
|
|
48
47
|
host: dbhost
|
49
48
|
pool: 5
|
50
49
|
timeout: 5000
|
51
|
-
db_id: 2 # ensure db_id is unique for each site
|
52
50
|
host_names:
|
53
51
|
- discuss.tardis.gallifrey
|
54
52
|
```
|
@@ -92,7 +90,7 @@ db_two:
|
|
92
90
|
To get a Rails console that is connected to `some_database_1` database:
|
93
91
|
|
94
92
|
```
|
95
|
-
|
93
|
+
RAILS_DB=db_one rails console
|
96
94
|
```
|
97
95
|
|
98
96
|
|
@@ -4,12 +4,17 @@ module RailsMultisite
|
|
4
4
|
class ConnectionManagement
|
5
5
|
|
6
6
|
DEFAULT = 'default'
|
7
|
+
SPEC_KLASS = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
7
8
|
|
8
9
|
def self.default_config_filename
|
9
10
|
File.absolute_path(Rails.root.to_s + "/config/multisite.yml")
|
10
11
|
end
|
11
12
|
|
12
13
|
def self.clear_settings!
|
14
|
+
@instance&.db_spec_cache&.each do |key, spec|
|
15
|
+
@instance.connection_handlers.delete(self.handler_key(spec))
|
16
|
+
end
|
17
|
+
|
13
18
|
@instance = nil
|
14
19
|
end
|
15
20
|
|
@@ -35,7 +40,7 @@ module RailsMultisite
|
|
35
40
|
end
|
36
41
|
|
37
42
|
def self.reload
|
38
|
-
@instance
|
43
|
+
@instance.reload
|
39
44
|
end
|
40
45
|
|
41
46
|
def self.has_db?(db)
|
@@ -97,6 +102,13 @@ module RailsMultisite
|
|
97
102
|
config[:host_names].nil? ? config[:host] : config[:host_names].first
|
98
103
|
end
|
99
104
|
|
105
|
+
def self.current_db_hostnames
|
106
|
+
spec = @instance.connection_spec(db: self.current_db) if @instance
|
107
|
+
spec ||= ActiveRecord::Base.connection_pool.spec
|
108
|
+
config = spec.config
|
109
|
+
config[:host_names].nil? ? [config[:host]] : config[:host_names]
|
110
|
+
end
|
111
|
+
|
100
112
|
def self.connection_spec(opts)
|
101
113
|
if @instance
|
102
114
|
@instance.connection_spec(opts)
|
@@ -113,12 +125,52 @@ module RailsMultisite
|
|
113
125
|
end
|
114
126
|
end
|
115
127
|
|
116
|
-
|
128
|
+
def self.handler_key(spec)
|
129
|
+
@handler_key_suffix ||= begin
|
130
|
+
if ActiveRecord::Base.respond_to?(:writing_role)
|
131
|
+
"_#{ActiveRecord::Base.writing_role}"
|
132
|
+
else
|
133
|
+
""
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
:"#{spec.name}#{@handler_key_suffix}"
|
138
|
+
end
|
139
|
+
|
140
|
+
def self.default_connection_handler=(connection_handler)
|
141
|
+
if @instance
|
142
|
+
unless connection_handler.is_a?(ActiveRecord::ConnectionAdapters::ConnectionHandler)
|
143
|
+
raise ArgumentError.new("Invalid connection handler")
|
144
|
+
end
|
145
|
+
|
146
|
+
@instance.default_connection_handler = connection_handler
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
attr_reader :config_filename, :db_spec_cache, :connection_handlers
|
151
|
+
attr_writer :default_connection_handler
|
117
152
|
|
118
153
|
def initialize(config_filename)
|
119
154
|
@config_filename = config_filename
|
120
155
|
|
121
|
-
|
156
|
+
@connection_handlers = begin
|
157
|
+
if ActiveRecord::Base.respond_to?(:connection_handlers)
|
158
|
+
ActiveRecord::Base.connection_handlers
|
159
|
+
else
|
160
|
+
{}
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
@db_spec_cache = {}
|
165
|
+
@default_spec = SPEC_KLASS::Resolver.new(ActiveRecord::Base.configurations).spec(Rails.env.to_sym)
|
166
|
+
@default_connection_handler = ActiveRecord::Base.connection_handler
|
167
|
+
|
168
|
+
@reload_mutex = Mutex.new
|
169
|
+
|
170
|
+
load_config!
|
171
|
+
end
|
172
|
+
|
173
|
+
def load_config!
|
122
174
|
configs = YAML::load(File.open(@config_filename))
|
123
175
|
|
124
176
|
no_prepared_statements = ActiveRecord::Base.configurations[Rails.env]["prepared_statements"] == false
|
@@ -136,27 +188,45 @@ module RailsMultisite
|
|
136
188
|
resolve_configs = ActiveRecord::DatabaseConfigurations.new(configs)
|
137
189
|
end
|
138
190
|
|
139
|
-
resolver =
|
140
|
-
@db_spec_cache = Hash[*configs.map { |k, _| [k, resolver.spec(k.to_sym)] }.flatten]
|
191
|
+
resolver = SPEC_KLASS::Resolver.new(resolve_configs)
|
141
192
|
|
142
|
-
|
193
|
+
# Build a hash of db name => spec
|
194
|
+
new_db_spec_cache = Hash[*configs.map { |k, _| [k, resolver.spec(k.to_sym)] }.flatten]
|
195
|
+
new_db_spec_cache.each do |k, v|
|
196
|
+
# If spec already existed, use the old version
|
197
|
+
if v&.to_hash == @db_spec_cache[k]&.to_hash
|
198
|
+
new_db_spec_cache[k] = @db_spec_cache[k]
|
199
|
+
end
|
200
|
+
end
|
143
201
|
|
202
|
+
# Build a hash of hostname => spec
|
203
|
+
new_host_spec_cache = {}
|
144
204
|
configs.each do |k, v|
|
145
205
|
next unless v["host_names"]
|
146
206
|
v["host_names"].each do |host|
|
147
|
-
|
207
|
+
new_host_spec_cache[host] = new_db_spec_cache[k]
|
148
208
|
end
|
149
209
|
end
|
150
210
|
|
151
|
-
|
211
|
+
# Add the default hostnames as well
|
152
212
|
ActiveRecord::Base.configurations[Rails.env]["host_names"].each do |host|
|
153
|
-
|
213
|
+
new_host_spec_cache[host] = @default_spec
|
154
214
|
end
|
155
215
|
|
156
|
-
|
216
|
+
removed_dbs = @db_spec_cache.keys - new_db_spec_cache.keys
|
217
|
+
removed_specs = @db_spec_cache.values_at(*removed_dbs)
|
218
|
+
|
219
|
+
@host_spec_cache = new_host_spec_cache
|
220
|
+
@db_spec_cache = new_db_spec_cache
|
157
221
|
|
158
|
-
|
159
|
-
@
|
222
|
+
# Clean up connection handler cache.
|
223
|
+
removed_specs.each { |s| @connection_handlers.delete(handler_key(s)) }
|
224
|
+
end
|
225
|
+
|
226
|
+
def reload
|
227
|
+
@reload_mutex.synchronize do
|
228
|
+
load_config!
|
229
|
+
end
|
160
230
|
end
|
161
231
|
|
162
232
|
def has_db?(db)
|
@@ -178,18 +248,14 @@ module RailsMultisite
|
|
178
248
|
spec ||= @default_spec
|
179
249
|
handler = nil
|
180
250
|
if spec != @default_spec
|
181
|
-
handler = @connection_handlers[spec]
|
251
|
+
handler = @connection_handlers[handler_key(spec)]
|
182
252
|
unless handler
|
183
253
|
handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
184
254
|
handler_establish_connection(handler, spec)
|
185
|
-
@connection_handlers[spec] = handler
|
255
|
+
@connection_handlers[handler_key(spec)] = handler
|
186
256
|
end
|
187
257
|
else
|
188
258
|
handler = @default_connection_handler
|
189
|
-
if !@established_default
|
190
|
-
handler_establish_connection(handler, spec)
|
191
|
-
@established_default = true
|
192
|
-
end
|
193
259
|
end
|
194
260
|
|
195
261
|
ActiveRecord::Base.connection_handler = handler
|
@@ -320,11 +386,11 @@ module RailsMultisite
|
|
320
386
|
private
|
321
387
|
|
322
388
|
def handler_establish_connection(handler, spec)
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
389
|
+
handler.establish_connection(spec.config)
|
390
|
+
end
|
391
|
+
|
392
|
+
def handler_key(spec)
|
393
|
+
self.class.handler_key(spec)
|
328
394
|
end
|
329
395
|
|
330
396
|
end
|
@@ -7,20 +7,28 @@ module RailsMultisite
|
|
7
7
|
end
|
8
8
|
|
9
9
|
initializer "RailsMultisite.init" do |app|
|
10
|
-
|
10
|
+
app.config.multisite = false
|
11
11
|
|
12
12
|
config_file = ConnectionManagement.default_config_filename
|
13
13
|
if File.exist?(config_file)
|
14
14
|
ConnectionManagement.config_filename = ConnectionManagement.default_config_filename
|
15
|
-
|
15
|
+
app.config.multisite = true
|
16
16
|
Rails.logger.formatter = RailsMultisite::Formatter.new
|
17
|
-
|
18
|
-
app.
|
17
|
+
|
18
|
+
if !skip_middleware?(app.config)
|
19
|
+
app.middleware.insert_after(ActionDispatch::Executor, RailsMultisite::Middleware)
|
20
|
+
app.middleware.delete(ActionDispatch::Executor)
|
21
|
+
end
|
19
22
|
|
20
23
|
if ENV['RAILS_DB'].present?
|
21
24
|
ConnectionManagement.establish_connection(db: ENV['RAILS_DB'], raise_on_missing: true)
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
28
|
+
|
29
|
+
def skip_middleware?(config)
|
30
|
+
return false if !config.respond_to?(:skip_multisite_middleware)
|
31
|
+
config.skip_multisite_middleware
|
32
|
+
end
|
25
33
|
end
|
26
34
|
end
|
data/lib/tasks/db.rake
CHANGED
data/lib/tasks/generators.rake
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
desc "generate multisite config file (if missing)"
|
2
3
|
task "multisite:generate:config" => :environment do
|
3
4
|
filename = RailsMultisite::ConnectionManagement.config_filename
|
@@ -14,7 +15,6 @@ task "multisite:generate:config" => :environment do
|
|
14
15
|
# host: localhost
|
15
16
|
# pool: 5
|
16
17
|
# timeout: 5000
|
17
|
-
# db_id: 1 # optionally include other settings you need
|
18
18
|
# host_names:
|
19
19
|
# - www.mysite.com
|
20
20
|
# - www.anothersite.com
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rails_multisite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,7 +16,7 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '5.0'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
22
|
version: '7'
|
@@ -26,7 +26,7 @@ dependencies:
|
|
26
26
|
requirements:
|
27
27
|
- - ">"
|
28
28
|
- !ruby/object:Gem::Version
|
29
|
-
version: '
|
29
|
+
version: '5.0'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
32
|
version: '7'
|
@@ -36,7 +36,7 @@ dependencies:
|
|
36
36
|
requirements:
|
37
37
|
- - ">"
|
38
38
|
- !ruby/object:Gem::Version
|
39
|
-
version: '
|
39
|
+
version: '5.0'
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
42
|
version: '7'
|
@@ -46,7 +46,7 @@ dependencies:
|
|
46
46
|
requirements:
|
47
47
|
- - ">"
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version: '
|
49
|
+
version: '5.0'
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
52
|
version: '7'
|
@@ -78,14 +78,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
78
78
|
requirements:
|
79
79
|
- - ">="
|
80
80
|
- !ruby/object:Gem::Version
|
81
|
-
version: 2.
|
81
|
+
version: 2.4.0
|
82
82
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
83
|
requirements:
|
84
84
|
- - ">="
|
85
85
|
- !ruby/object:Gem::Version
|
86
86
|
version: '0'
|
87
87
|
requirements: []
|
88
|
-
rubygems_version: 3.
|
88
|
+
rubygems_version: 3.1.2
|
89
89
|
signing_key:
|
90
90
|
specification_version: 4
|
91
91
|
summary: Multi tenancy support for Rails
|