rails_multisite 2.0.7 → 2.3.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.
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
|