rails_multisite 1.1.2 → 2.0.1
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/lib/rails_multisite.rb +1 -0
- data/lib/rails_multisite/connection_management.rb +178 -129
- data/lib/rails_multisite/middleware.rb +30 -0
- data/lib/rails_multisite/railtie.rb +4 -5
- data/lib/rails_multisite/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 21426e08679ae314cc95d1b9e3a4271b16a53e39
|
4
|
+
data.tar.gz: b748de947d54cb1991caeb9fd32f6e9a323e3462
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2f77faddf9cf3ccd3e6d787066afa2c9e2791208d1c0e9ae0780f171c7c2147691030b82b3f31d4168c0f626eb5b82daca96bf5487ea78ba8df283f07c9b79c1
|
7
|
+
data.tar.gz: 804ea79e00fdcaf13b255035fcfb13201e379187a625610cd06ffacdf321a57b54cb25d1c3fb0764879adda4b8c1ad1b4bf86bcb74f836657ff93ebfb508e634
|
data/lib/rails_multisite.rb
CHANGED
@@ -2,57 +2,186 @@
|
|
2
2
|
#
|
3
3
|
module RailsMultisite
|
4
4
|
class ConnectionManagement
|
5
|
-
|
5
|
+
|
6
6
|
DEFAULT = 'default'
|
7
7
|
|
8
|
+
def self.default_config_filename
|
9
|
+
File.absolute_path(Rails.root.to_s + "/config/multisite.yml")
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.clear_settings!
|
13
|
+
@instance = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.load_settings!
|
17
|
+
# no op only here backwards compat
|
18
|
+
STDERR.puts "RailsMultisite::ConnectionManagement.load_settings! is deprecated"
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.instance
|
22
|
+
@instance
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.config_filename=(config_filename)
|
26
|
+
if config_filename.nil?
|
27
|
+
@instance = nil
|
28
|
+
else
|
29
|
+
@instance = new(config_filename)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.config_filename
|
34
|
+
@instance.config_filename
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.reload
|
38
|
+
@instance = new(instance.config_filename)
|
39
|
+
end
|
40
|
+
|
8
41
|
def self.has_db?(db)
|
9
42
|
return true if db == DEFAULT
|
10
|
-
(
|
43
|
+
!!(@instance && @instance.has_db?(db))
|
11
44
|
end
|
12
45
|
|
13
|
-
def self.
|
14
|
-
|
46
|
+
def self.establish_connection(opts)
|
47
|
+
@instance.establish_connection(opts) if @instance
|
15
48
|
end
|
16
49
|
|
17
|
-
def self.
|
18
|
-
|
50
|
+
def self.with_hostname(hostname, &blk)
|
51
|
+
if @instance
|
52
|
+
@instance.with_hostname(hostname, &blk)
|
53
|
+
else
|
54
|
+
blk.call hostname
|
55
|
+
end
|
56
|
+
end
|
19
57
|
|
20
|
-
|
21
|
-
|
58
|
+
def self.with_connection(db = DEFAULT, &blk)
|
59
|
+
if @instance
|
60
|
+
@instance.with_connection(db, &blk)
|
22
61
|
else
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
62
|
+
connected = ActiveRecord::Base.connection_pool.connected?
|
63
|
+
blk.call db
|
64
|
+
ActiveRecord::Base.clear_active_connections! unless connected
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def self.each_connection(opts = nil, &blk)
|
69
|
+
if @instance
|
70
|
+
@instance.each_connection(opts, &blk)
|
71
|
+
else
|
72
|
+
with_connection(&blk)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.all_dbs
|
77
|
+
if @instance
|
78
|
+
@instance.all_dbs
|
79
|
+
else
|
80
|
+
[DEFAULT]
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def self.current_db
|
85
|
+
if @instance
|
86
|
+
instance.current_db
|
87
|
+
else
|
88
|
+
DEFAULT
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def self.current_hostname
|
93
|
+
config = ActiveRecord::Base.connection_pool.spec.config
|
94
|
+
config[:host_names].nil? ? config[:host] : config[:host_names].first
|
95
|
+
end
|
96
|
+
|
97
|
+
def self.connection_spec(opts)
|
98
|
+
if @instance
|
99
|
+
@instance.connection_spec(opts)
|
100
|
+
else
|
101
|
+
ActiveRecord::Base.connection_pool.spec
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.host(env)
|
106
|
+
if @instance
|
107
|
+
@instance.host(env)
|
108
|
+
else
|
109
|
+
env["HTTP_HOST"]
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
attr_reader :config_filename
|
114
|
+
|
115
|
+
def initialize(config_filename)
|
116
|
+
@config_filename = config_filename
|
117
|
+
|
118
|
+
spec_klass = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
119
|
+
configs = YAML::load(File.open(@config_filename))
|
120
|
+
|
121
|
+
no_prepared_statements = ActiveRecord::Base.configurations[Rails.env]["prepared_statements"] == false
|
122
|
+
|
123
|
+
configs.each do |k, v|
|
124
|
+
raise ArgumentError.new("Please do not name any db default!") if k == DEFAULT
|
125
|
+
v[:db_key] = k
|
126
|
+
v[:prepared_statements] = false if no_prepared_statements
|
127
|
+
end
|
128
|
+
|
129
|
+
resolver = spec_klass::Resolver.new(configs)
|
130
|
+
@db_spec_cache = Hash[*configs.map { |k, _| [k, resolver.spec(k.to_sym)] }.flatten]
|
131
|
+
|
132
|
+
@host_spec_cache = {}
|
133
|
+
|
134
|
+
configs.each do |k, v|
|
135
|
+
next unless v["host_names"]
|
136
|
+
v["host_names"].each do |host|
|
137
|
+
@host_spec_cache[host] = @db_spec_cache[k]
|
42
138
|
end
|
139
|
+
end
|
43
140
|
|
44
|
-
|
141
|
+
@default_spec = spec_klass::Resolver.new(ActiveRecord::Base.configurations).spec(Rails.env.to_sym)
|
142
|
+
ActiveRecord::Base.configurations[Rails.env]["host_names"].each do |host|
|
143
|
+
@host_spec_cache[host] = @default_spec
|
45
144
|
end
|
145
|
+
|
146
|
+
@default_connection_handler = ActiveRecord::Base.connection_handler
|
147
|
+
|
148
|
+
@connection_handlers = {}
|
149
|
+
@established_default = false
|
46
150
|
end
|
47
151
|
|
48
|
-
def
|
152
|
+
def has_db?(db)
|
153
|
+
return true if db == DEFAULT
|
154
|
+
@db_spec_cache[db]
|
155
|
+
end
|
156
|
+
|
157
|
+
def establish_connection(opts)
|
158
|
+
opts[:db] = opts[:db].to_s
|
49
159
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
160
|
+
spec = connection_spec(opts)
|
161
|
+
if (!spec && opts[:raise_on_missing])
|
162
|
+
raise "ERROR: #{opts[:db]} not found!"
|
163
|
+
end
|
164
|
+
spec ||= @default_spec
|
165
|
+
handler = nil
|
166
|
+
if spec != @default_spec
|
167
|
+
handler = @connection_handlers[spec]
|
168
|
+
unless handler
|
169
|
+
handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
170
|
+
handler_establish_connection(handler, spec)
|
171
|
+
@connection_handlers[spec] = handler
|
172
|
+
end
|
173
|
+
else
|
174
|
+
handler = @default_connection_handler
|
175
|
+
if !@established_default
|
176
|
+
handler_establish_connection(handler, spec)
|
177
|
+
@established_default = true
|
178
|
+
end
|
54
179
|
end
|
55
180
|
|
181
|
+
ActiveRecord::Base.connection_handler = handler
|
182
|
+
end
|
183
|
+
|
184
|
+
def with_hostname(hostname)
|
56
185
|
old = current_hostname
|
57
186
|
connected = ActiveRecord::Base.connection_pool.connected?
|
58
187
|
|
@@ -69,7 +198,7 @@ module RailsMultisite
|
|
69
198
|
rval
|
70
199
|
end
|
71
200
|
|
72
|
-
def
|
201
|
+
def with_connection(db = DEFAULT)
|
73
202
|
old = current_db
|
74
203
|
connected = ActiveRecord::Base.connection_pool.connected?
|
75
204
|
|
@@ -86,7 +215,7 @@ module RailsMultisite
|
|
86
215
|
rval
|
87
216
|
end
|
88
217
|
|
89
|
-
def
|
218
|
+
def each_connection(opts = nil, &blk)
|
90
219
|
|
91
220
|
old = current_db
|
92
221
|
connected = ActiveRecord::Base.connection_pool.connected?
|
@@ -143,120 +272,40 @@ module RailsMultisite
|
|
143
272
|
ActiveRecord::Base.connection_handler.clear_active_connections! unless connected
|
144
273
|
end
|
145
274
|
|
146
|
-
def
|
147
|
-
[DEFAULT] +
|
148
|
-
if defined?(@@db_spec_cache) && @@db_spec_cache
|
149
|
-
@@db_spec_cache.keys.to_a
|
150
|
-
else
|
151
|
-
[]
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
def self.set_current_db
|
156
|
-
@@current_db = DEFAULT
|
275
|
+
def all_dbs
|
276
|
+
[DEFAULT] + @db_spec_cache.keys.to_a
|
157
277
|
end
|
158
278
|
|
159
|
-
def
|
160
|
-
return @@current_db if defined?(@@current_db)
|
279
|
+
def current_db
|
161
280
|
ActiveRecord::Base.connection_pool.spec.config[:db_key] || DEFAULT
|
162
281
|
end
|
163
282
|
|
164
|
-
def
|
165
|
-
|
166
|
-
end
|
167
|
-
|
168
|
-
def self.config_filename
|
169
|
-
@@config_filename ||= File.absolute_path(Rails.root.to_s + "/" + RailsMultisite::ConnectionManagement::CONFIG_FILE)
|
170
|
-
end
|
171
|
-
|
172
|
-
def self.current_hostname
|
173
|
-
config = ActiveRecord::Base.connection_pool.spec.config
|
174
|
-
config[:host_names].nil? ? config[:host] : config[:host_names].first
|
175
|
-
end
|
176
|
-
|
177
|
-
def self.clear_settings!
|
178
|
-
@@db_spec_cache = nil
|
179
|
-
@@host_spec_cache = nil
|
180
|
-
@@default_spec = nil
|
283
|
+
def current_hostname
|
284
|
+
ConnectionManagement.current_hostname
|
181
285
|
end
|
182
286
|
|
183
|
-
def
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
no_prepared_statements = ActiveRecord::Base.configurations[Rails.env]["prepared_statements"] == false
|
188
|
-
|
189
|
-
configs.each do |k, v|
|
190
|
-
raise ArgumentError.new("Please do not name any db default!") if k == DEFAULT
|
191
|
-
v[:db_key] = k
|
192
|
-
v[:prepared_statements] = false if no_prepared_statements
|
287
|
+
def host(env)
|
288
|
+
if host = env["RAILS_MULTISITE_HOST"]
|
289
|
+
return host
|
193
290
|
end
|
194
291
|
|
195
|
-
resolver = spec_klass::Resolver.new(configs)
|
196
|
-
@@db_spec_cache = Hash[*configs.map { |k, _| [k, resolver.spec(k.to_sym)] }.flatten]
|
197
|
-
|
198
|
-
@@host_spec_cache = {}
|
199
|
-
configs.each do |k, v|
|
200
|
-
next unless v["host_names"]
|
201
|
-
v["host_names"].each do |host|
|
202
|
-
@@host_spec_cache[host] = @@db_spec_cache[k]
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
@@default_spec = spec_klass::Resolver.new(ActiveRecord::Base.configurations).spec(Rails.env.to_sym)
|
207
|
-
ActiveRecord::Base.configurations[Rails.env]["host_names"].each do |host|
|
208
|
-
@@host_spec_cache[host] = @@default_spec
|
209
|
-
end
|
210
|
-
|
211
|
-
@@default_connection_handler = ActiveRecord::Base.connection_handler
|
212
|
-
|
213
|
-
@@connection_handlers = {}
|
214
|
-
@@established_default = false
|
215
|
-
end
|
216
|
-
|
217
|
-
def initialize(app, config = nil)
|
218
|
-
@app = app
|
219
|
-
@db_lookup = config && config[:db_lookup]
|
220
|
-
end
|
221
|
-
|
222
|
-
def self.host(env)
|
223
292
|
request = Rack::Request.new(env)
|
224
|
-
request['__ws'] || request.host
|
225
|
-
end
|
226
|
-
|
227
|
-
def call(env)
|
228
|
-
host = self.class.host(env)
|
229
|
-
db = nil
|
230
|
-
begin
|
231
|
-
|
232
|
-
unless @@host_spec_cache[host]
|
233
|
-
db = @db_lookup && @db_lookup.call(env)
|
234
|
-
if db
|
235
|
-
host = nil
|
236
|
-
else
|
237
|
-
return [404, {}, ["not found"]]
|
238
|
-
end
|
239
|
-
end
|
293
|
+
host = request['__ws'] || request.host
|
240
294
|
|
241
|
-
|
242
|
-
self.class.establish_connection(host: host, db: db)
|
243
|
-
@app.call(env)
|
244
|
-
ensure
|
245
|
-
ActiveRecord::Base.connection_handler.clear_active_connections!
|
246
|
-
end
|
295
|
+
env["RAILS_MULTISITE_HOST"] = host
|
247
296
|
end
|
248
297
|
|
249
|
-
def
|
298
|
+
def connection_spec(opts)
|
250
299
|
if opts[:host]
|
251
|
-
|
300
|
+
@host_spec_cache[opts[:host]]
|
252
301
|
else
|
253
|
-
|
302
|
+
@db_spec_cache[opts[:db]]
|
254
303
|
end
|
255
304
|
end
|
256
305
|
|
257
306
|
private
|
258
307
|
|
259
|
-
def
|
308
|
+
def handler_establish_connection(handler, spec)
|
260
309
|
if Rails::VERSION::MAJOR >= 5
|
261
310
|
handler.establish_connection(spec.config)
|
262
311
|
else
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module RailsMultisite
|
2
|
+
class Middleware
|
3
|
+
def initialize(app, config = nil)
|
4
|
+
@app = app
|
5
|
+
@db_lookup = config && config[:db_lookup]
|
6
|
+
end
|
7
|
+
|
8
|
+
def call(env)
|
9
|
+
host = ConnectionManagement.host(env)
|
10
|
+
db = nil
|
11
|
+
begin
|
12
|
+
|
13
|
+
unless ConnectionManagement.connection_spec(host: host)
|
14
|
+
db = @db_lookup && @db_lookup.call(env)
|
15
|
+
if db
|
16
|
+
host = nil
|
17
|
+
else
|
18
|
+
return [404, {}, ["not found"]]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!
|
23
|
+
ConnectionManagement.establish_connection(host: host, db: db)
|
24
|
+
@app.call(env)
|
25
|
+
ensure
|
26
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -9,18 +9,17 @@ module RailsMultisite
|
|
9
9
|
initializer "RailsMultisite.init" do |app|
|
10
10
|
Rails.configuration.multisite = false
|
11
11
|
|
12
|
-
|
12
|
+
config_file = ConnectionManagement.default_config_filename
|
13
|
+
if File.exist?(config_file)
|
14
|
+
ConnectionManagement.config_filename = ConnectionManagement.default_config_filename
|
13
15
|
Rails.configuration.multisite = true
|
14
16
|
Rails.logger.formatter = RailsMultisite::Formatter.new
|
15
|
-
|
16
|
-
app.middleware.insert_after(ActionDispatch::Executor, RailsMultisite::ConnectionManagement)
|
17
|
+
app.middleware.insert_after(ActionDispatch::Executor, RailsMultisite::Middleware)
|
17
18
|
app.middleware.delete(ActionDispatch::Executor)
|
18
19
|
|
19
20
|
if ENV['RAILS_DB'].present?
|
20
21
|
ConnectionManagement.establish_connection(db: ENV['RAILS_DB'], raise_on_missing: true)
|
21
22
|
end
|
22
|
-
else
|
23
|
-
ConnectionManagement.set_current_db
|
24
23
|
end
|
25
24
|
end
|
26
25
|
end
|
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:
|
4
|
+
version: 2.0.1
|
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: 2018-01-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -62,6 +62,7 @@ files:
|
|
62
62
|
- lib/rails_multisite.rb
|
63
63
|
- lib/rails_multisite/connection_management.rb
|
64
64
|
- lib/rails_multisite/formatter.rb
|
65
|
+
- lib/rails_multisite/middleware.rb
|
65
66
|
- lib/rails_multisite/railtie.rb
|
66
67
|
- lib/rails_multisite/version.rb
|
67
68
|
- lib/tasks/db.rake
|