rails_multisite 5.0.0 → 5.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.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9b49ebb943b1cf7656cce41a93e6100b50159a5c7e389ef9629247b385b38c94
|
4
|
+
data.tar.gz: 93e51dcd1d7e91056e5643dc2b6220397e8c2672ed267aef342ebbb27efe15a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 430d520b818f54f3b78eef444bc929542149c17852041ae42bd221d47188dacf927fead066ec49feae6c776d1ad2446c6ec27dae60a7d4e7e2758f407ec64921
|
7
|
+
data.tar.gz: adac4e78e18303464728db9b26f5124f4ebcf01ebf5081e8aa15d7a8103464b46ab0698facefe0d668e78e34600282cc74e53ba93a0de0ac1909b4db44d9e60d
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RailsMultisite
|
4
|
+
class ConnectionManagement
|
5
|
+
class NullInstance
|
6
|
+
include Singleton
|
7
|
+
|
8
|
+
def clear_settings!
|
9
|
+
end
|
10
|
+
|
11
|
+
def config_filename
|
12
|
+
end
|
13
|
+
|
14
|
+
def default_connection_handler=(_connection_handler)
|
15
|
+
end
|
16
|
+
|
17
|
+
def establish_connection(_opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
def reload
|
21
|
+
end
|
22
|
+
|
23
|
+
def all_dbs
|
24
|
+
[DEFAULT]
|
25
|
+
end
|
26
|
+
|
27
|
+
def connection_spec(_opts)
|
28
|
+
ConnectionSpecification.current
|
29
|
+
end
|
30
|
+
|
31
|
+
def current_db
|
32
|
+
DEFAULT
|
33
|
+
end
|
34
|
+
|
35
|
+
def each_connection(_opts = nil, &blk)
|
36
|
+
with_connection(&blk)
|
37
|
+
end
|
38
|
+
|
39
|
+
def has_db?(db)
|
40
|
+
db == DEFAULT
|
41
|
+
end
|
42
|
+
|
43
|
+
def host(env)
|
44
|
+
env["HTTP_HOST"]
|
45
|
+
end
|
46
|
+
|
47
|
+
def with_connection(db = DEFAULT, &blk)
|
48
|
+
connected = ActiveRecord::Base.connection_pool.connected?
|
49
|
+
result = blk.call(db)
|
50
|
+
unless connected
|
51
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!
|
52
|
+
end
|
53
|
+
result
|
54
|
+
end
|
55
|
+
|
56
|
+
def with_hostname(hostname, &blk)
|
57
|
+
blk.call(hostname)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -1,166 +1,91 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
if Rails.version >=
|
4
|
-
require
|
3
|
+
if Rails.version >= "6.1"
|
4
|
+
require "rails_multisite/connection_management/rails_61_compat"
|
5
5
|
else
|
6
|
-
require
|
6
|
+
require "rails_multisite/connection_management/rails_60_compat"
|
7
7
|
end
|
8
|
+
require "rails_multisite/connection_management/null_instance"
|
8
9
|
|
9
10
|
module RailsMultisite
|
10
11
|
class ConnectionManagement
|
11
|
-
DEFAULT =
|
12
|
+
DEFAULT = "default"
|
12
13
|
|
13
14
|
cattr_accessor :connection_handlers, default: {}
|
14
15
|
|
15
|
-
|
16
|
-
File.absolute_path(Rails.root.to_s + "/config/multisite.yml")
|
17
|
-
end
|
16
|
+
attr_reader :config_filename, :db_spec_cache
|
18
17
|
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
class << self
|
19
|
+
attr_accessor :asset_hostnames
|
20
|
+
|
21
|
+
delegate :all_dbs,
|
22
|
+
:config_filename,
|
23
|
+
:connection_spec,
|
24
|
+
:current_db,
|
25
|
+
:default_connection_handler=,
|
26
|
+
:each_connection,
|
27
|
+
:establish_connection,
|
28
|
+
:has_db?,
|
29
|
+
:host,
|
30
|
+
:reload,
|
31
|
+
:with_connection,
|
32
|
+
:with_hostname,
|
33
|
+
to: :instance
|
34
|
+
|
35
|
+
def default_config_filename
|
36
|
+
File.absolute_path(Rails.root.to_s + "/config/multisite.yml")
|
22
37
|
end
|
23
38
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
def self.load_settings!
|
28
|
-
# no op only here backwards compat
|
29
|
-
STDERR.puts "RailsMultisite::ConnectionManagement.load_settings! is deprecated"
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.instance
|
33
|
-
@instance
|
34
|
-
end
|
35
|
-
|
36
|
-
def self.config_filename=(config_filename)
|
37
|
-
if config_filename.nil?
|
39
|
+
def clear_settings!
|
40
|
+
instance.clear_settings!
|
38
41
|
@instance = nil
|
39
|
-
else
|
40
|
-
@instance = new(config_filename)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def self.asset_hostnames
|
45
|
-
@asset_hostnames
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.asset_hostnames=(h)
|
49
|
-
@asset_hostnames = h
|
50
|
-
end
|
51
|
-
|
52
|
-
def self.config_filename
|
53
|
-
@instance.config_filename
|
54
|
-
end
|
55
|
-
|
56
|
-
def self.reload
|
57
|
-
@instance.reload
|
58
|
-
end
|
59
|
-
|
60
|
-
def self.has_db?(db)
|
61
|
-
return true if db == DEFAULT
|
62
|
-
!!(@instance && @instance.has_db?(db))
|
63
|
-
end
|
64
|
-
|
65
|
-
def self.establish_connection(opts)
|
66
|
-
@instance.establish_connection(opts) if @instance
|
67
|
-
end
|
68
|
-
|
69
|
-
def self.with_hostname(hostname, &blk)
|
70
|
-
if @instance
|
71
|
-
@instance.with_hostname(hostname, &blk)
|
72
|
-
else
|
73
|
-
blk.call hostname
|
74
|
-
end
|
75
|
-
end
|
76
|
-
|
77
|
-
def self.with_connection(db = DEFAULT, &blk)
|
78
|
-
if @instance
|
79
|
-
@instance.with_connection(db, &blk)
|
80
|
-
else
|
81
|
-
connected = ActiveRecord::Base.connection_pool.connected?
|
82
|
-
result = blk.call db
|
83
|
-
ActiveRecord::Base.clear_active_connections! unless connected
|
84
|
-
result
|
85
|
-
end
|
86
|
-
end
|
87
|
-
|
88
|
-
def self.each_connection(opts = nil, &blk)
|
89
|
-
if @instance
|
90
|
-
@instance.each_connection(opts, &blk)
|
91
|
-
else
|
92
|
-
with_connection(&blk)
|
93
42
|
end
|
94
|
-
end
|
95
43
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
else
|
100
|
-
[DEFAULT]
|
44
|
+
def load_settings!
|
45
|
+
# no op only here backwards compat
|
46
|
+
STDERR.puts "RailsMultisite::ConnectionManagement.load_settings! is deprecated"
|
101
47
|
end
|
102
|
-
end
|
103
48
|
|
104
|
-
|
105
|
-
|
106
|
-
instance.current_db
|
107
|
-
else
|
108
|
-
DEFAULT
|
49
|
+
def instance
|
50
|
+
@instance || NullInstance.instance
|
109
51
|
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def self.current_hostname
|
113
|
-
current_db_hostnames.first
|
114
|
-
end
|
115
52
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
if @instance
|
123
|
-
@instance.connection_spec(opts)
|
124
|
-
else
|
125
|
-
ConnectionSpecification.current
|
53
|
+
def config_filename=(config_filename)
|
54
|
+
if config_filename.blank?
|
55
|
+
@instance = nil
|
56
|
+
else
|
57
|
+
@instance = new(config_filename)
|
58
|
+
end
|
126
59
|
end
|
127
|
-
end
|
128
60
|
|
129
|
-
|
130
|
-
|
131
|
-
@instance.host(env)
|
132
|
-
else
|
133
|
-
env["HTTP_HOST"]
|
61
|
+
def current_hostname
|
62
|
+
current_db_hostnames.first
|
134
63
|
end
|
135
|
-
end
|
136
64
|
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
else
|
144
|
-
""
|
145
|
-
end
|
65
|
+
def current_db_hostnames
|
66
|
+
config =
|
67
|
+
(
|
68
|
+
connection_spec(db: current_db) || ConnectionSpecification.current
|
69
|
+
).config
|
70
|
+
config[:host_names] || [config[:host]]
|
146
71
|
end
|
147
72
|
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
73
|
+
def handler_key(spec)
|
74
|
+
@handler_key_suffix ||=
|
75
|
+
begin
|
76
|
+
if ActiveRecord.respond_to?(:writing_role)
|
77
|
+
"_#{ActiveRecord.writing_role}"
|
78
|
+
elsif ActiveRecord::Base.respond_to?(:writing_role)
|
79
|
+
"_#{ActiveRecord::Base.writing_role}"
|
80
|
+
else
|
81
|
+
""
|
82
|
+
end
|
83
|
+
end
|
156
84
|
|
157
|
-
@
|
85
|
+
:"#{spec.name}#{@handler_key_suffix}"
|
158
86
|
end
|
159
87
|
end
|
160
88
|
|
161
|
-
attr_reader :config_filename, :db_spec_cache
|
162
|
-
attr_writer :default_connection_handler
|
163
|
-
|
164
89
|
def initialize(config_filename)
|
165
90
|
@config_filename = config_filename
|
166
91
|
|
@@ -174,12 +99,15 @@ module RailsMultisite
|
|
174
99
|
end
|
175
100
|
|
176
101
|
def load_config!
|
177
|
-
configs = YAML.safe_load(File.open(
|
102
|
+
configs = YAML.safe_load(File.open(config_filename))
|
178
103
|
|
179
|
-
no_prepared_statements =
|
104
|
+
no_prepared_statements =
|
105
|
+
@default_spec.config[:prepared_statements] == false
|
180
106
|
|
181
107
|
configs.each do |k, v|
|
182
|
-
|
108
|
+
if k == DEFAULT
|
109
|
+
raise ArgumentError.new("Please do not name any db default!")
|
110
|
+
end
|
183
111
|
v[:db_key] = k
|
184
112
|
v[:prepared_statements] = false if no_prepared_statements
|
185
113
|
end
|
@@ -188,8 +116,8 @@ module RailsMultisite
|
|
188
116
|
new_db_spec_cache = ConnectionSpecification.db_spec_cache(configs)
|
189
117
|
new_db_spec_cache.each do |k, v|
|
190
118
|
# If spec already existed, use the old version
|
191
|
-
if v&.to_hash ==
|
192
|
-
new_db_spec_cache[k] =
|
119
|
+
if v&.to_hash == db_spec_cache[k]&.to_hash
|
120
|
+
new_db_spec_cache[k] = db_spec_cache[k]
|
193
121
|
end
|
194
122
|
end
|
195
123
|
|
@@ -207,8 +135,8 @@ module RailsMultisite
|
|
207
135
|
new_host_spec_cache[host] = @default_spec
|
208
136
|
end
|
209
137
|
|
210
|
-
removed_dbs =
|
211
|
-
removed_specs =
|
138
|
+
removed_dbs = db_spec_cache.keys - new_db_spec_cache.keys
|
139
|
+
removed_specs = db_spec_cache.values_at(*removed_dbs)
|
212
140
|
|
213
141
|
@host_spec_cache = new_host_spec_cache
|
214
142
|
@db_spec_cache = new_db_spec_cache
|
@@ -218,14 +146,11 @@ module RailsMultisite
|
|
218
146
|
end
|
219
147
|
|
220
148
|
def reload
|
221
|
-
@reload_mutex.synchronize
|
222
|
-
load_config!
|
223
|
-
end
|
149
|
+
@reload_mutex.synchronize { load_config! }
|
224
150
|
end
|
225
151
|
|
226
152
|
def has_db?(db)
|
227
|
-
|
228
|
-
@db_spec_cache[db]
|
153
|
+
db == DEFAULT || !!db_spec_cache[db]
|
229
154
|
end
|
230
155
|
|
231
156
|
def establish_connection(opts)
|
@@ -245,7 +170,7 @@ module RailsMultisite
|
|
245
170
|
handler = connection_handlers[handler_key(spec)]
|
246
171
|
unless handler
|
247
172
|
handler = ActiveRecord::ConnectionAdapters::ConnectionHandler.new
|
248
|
-
|
173
|
+
handler.establish_connection(spec.config)
|
249
174
|
connection_handlers[handler_key(spec)] = handler
|
250
175
|
end
|
251
176
|
else
|
@@ -266,7 +191,9 @@ module RailsMultisite
|
|
266
191
|
ActiveRecord::Base.connection_handler.clear_active_connections!
|
267
192
|
|
268
193
|
establish_connection(host: old)
|
269
|
-
|
194
|
+
unless connected
|
195
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!
|
196
|
+
end
|
270
197
|
end
|
271
198
|
|
272
199
|
rval
|
@@ -283,14 +210,15 @@ module RailsMultisite
|
|
283
210
|
ActiveRecord::Base.connection_handler.clear_active_connections!
|
284
211
|
|
285
212
|
establish_connection(db: old)
|
286
|
-
|
213
|
+
unless connected
|
214
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!
|
215
|
+
end
|
287
216
|
end
|
288
217
|
|
289
218
|
rval
|
290
219
|
end
|
291
220
|
|
292
221
|
def each_connection(opts = nil, &blk)
|
293
|
-
|
294
222
|
old = current_db
|
295
223
|
connected = ActiveRecord::Base.connection_pool.connected?
|
296
224
|
|
@@ -305,30 +233,32 @@ module RailsMultisite
|
|
305
233
|
errors = nil
|
306
234
|
|
307
235
|
if queue
|
308
|
-
threads
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
236
|
+
threads
|
237
|
+
.times
|
238
|
+
.map do
|
239
|
+
Thread.new do
|
240
|
+
while true
|
241
|
+
begin
|
242
|
+
db = queue.deq(true)
|
243
|
+
rescue ThreadError
|
244
|
+
db = nil
|
245
|
+
end
|
246
|
+
|
247
|
+
break unless db
|
248
|
+
|
249
|
+
establish_connection(db: db)
|
250
|
+
# no choice but to rescue, should probably log
|
251
|
+
|
252
|
+
begin
|
253
|
+
blk.call(db)
|
254
|
+
rescue => e
|
255
|
+
(errors ||= []) << e
|
256
|
+
end
|
257
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!
|
327
258
|
end
|
328
|
-
ActiveRecord::Base.connection_handler.clear_active_connections!
|
329
259
|
end
|
330
260
|
end
|
331
|
-
|
261
|
+
.map(&:join)
|
332
262
|
else
|
333
263
|
all_dbs.each do |db|
|
334
264
|
establish_connection(db: db)
|
@@ -340,14 +270,15 @@ module RailsMultisite
|
|
340
270
|
if errors && errors.length > 0
|
341
271
|
raise StandardError, "Failed to run queries #{errors.inspect}"
|
342
272
|
end
|
343
|
-
|
344
273
|
ensure
|
345
274
|
establish_connection(db: old)
|
346
|
-
|
275
|
+
unless connected
|
276
|
+
ActiveRecord::Base.connection_handler.clear_active_connections!
|
277
|
+
end
|
347
278
|
end
|
348
279
|
|
349
280
|
def all_dbs
|
350
|
-
[DEFAULT] +
|
281
|
+
[DEFAULT] + db_spec_cache.keys.to_a
|
351
282
|
end
|
352
283
|
|
353
284
|
def current_db
|
@@ -366,9 +297,9 @@ module RailsMultisite
|
|
366
297
|
request = Rack::Request.new(env)
|
367
298
|
|
368
299
|
host =
|
369
|
-
if request[
|
300
|
+
if request["__ws"] && self.class.asset_hostnames&.include?(request.host)
|
370
301
|
request.cookies.clear
|
371
|
-
request[
|
302
|
+
request["__ws"]
|
372
303
|
else
|
373
304
|
request.host
|
374
305
|
end
|
@@ -377,22 +308,29 @@ module RailsMultisite
|
|
377
308
|
end
|
378
309
|
|
379
310
|
def connection_spec(opts)
|
380
|
-
|
381
|
-
|
382
|
-
|
383
|
-
|
311
|
+
opts[:host] ? @host_spec_cache[opts[:host]] : db_spec_cache[opts[:db]]
|
312
|
+
end
|
313
|
+
|
314
|
+
def clear_settings!
|
315
|
+
db_spec_cache.each do |key, spec|
|
316
|
+
connection_handlers.delete(handler_key(spec))
|
384
317
|
end
|
385
318
|
end
|
386
319
|
|
387
|
-
|
320
|
+
def default_connection_handler=(connection_handler)
|
321
|
+
unless connection_handler.is_a?(
|
322
|
+
ActiveRecord::ConnectionAdapters::ConnectionHandler
|
323
|
+
)
|
324
|
+
raise ArgumentError.new("Invalid connection handler")
|
325
|
+
end
|
388
326
|
|
389
|
-
|
390
|
-
handler.establish_connection(spec.config)
|
327
|
+
@default_connection_handler = connection_handler
|
391
328
|
end
|
392
329
|
|
330
|
+
private
|
331
|
+
|
393
332
|
def handler_key(spec)
|
394
333
|
self.class.handler_key(spec)
|
395
334
|
end
|
396
|
-
|
397
335
|
end
|
398
336
|
end
|
data/lib/tasks/generators.rake
CHANGED
@@ -3,7 +3,7 @@ desc "generate multisite config file (if missing)"
|
|
3
3
|
task "multisite:generate:config" => :environment do
|
4
4
|
filename = RailsMultisite::ConnectionManagement.config_filename
|
5
5
|
|
6
|
-
if File.
|
6
|
+
if File.exist?(filename)
|
7
7
|
puts "Config is already generated at #{RailsMultisite::ConnectionManagement::CONFIG_FILE}"
|
8
8
|
else
|
9
9
|
puts "Generated config file at #{RailsMultisite::ConnectionManagement::CONFIG_FILE}"
|
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: 5.0.
|
4
|
+
version: 5.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Saffron
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-03-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -49,6 +49,7 @@ files:
|
|
49
49
|
- README.md
|
50
50
|
- lib/rails_multisite.rb
|
51
51
|
- lib/rails_multisite/connection_management.rb
|
52
|
+
- lib/rails_multisite/connection_management/null_instance.rb
|
52
53
|
- lib/rails_multisite/connection_management/rails_60_compat.rb
|
53
54
|
- lib/rails_multisite/connection_management/rails_61_compat.rb
|
54
55
|
- lib/rails_multisite/cookie_salt.rb
|
@@ -61,7 +62,7 @@ files:
|
|
61
62
|
homepage: ''
|
62
63
|
licenses: []
|
63
64
|
metadata: {}
|
64
|
-
post_install_message:
|
65
|
+
post_install_message:
|
65
66
|
rdoc_options: []
|
66
67
|
require_paths:
|
67
68
|
- lib
|
@@ -76,8 +77,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
76
77
|
- !ruby/object:Gem::Version
|
77
78
|
version: '0'
|
78
79
|
requirements: []
|
79
|
-
rubygems_version: 3.
|
80
|
-
signing_key:
|
80
|
+
rubygems_version: 3.5.3
|
81
|
+
signing_key:
|
81
82
|
specification_version: 4
|
82
83
|
summary: Multi tenancy support for Rails
|
83
84
|
test_files: []
|