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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a0e0f9bb773343cb717c3342bdba03296eb1d7f298a26527aa435309aba5c71
4
- data.tar.gz: 8b2d59de4f66e24d753f72b4bf43618769178191e3b25a1117b8a0fd4460e0a0
3
+ metadata.gz: 2acf52c9b8002bff6a1590222b85d778cb1ddd9e28de6ac91eed45d5117e30aa
4
+ data.tar.gz: 3b39a8d9a2d2b70c62e29a0541d585c499a51cb9ac6b8dac2544343b1c22d45c
5
5
  SHA512:
6
- metadata.gz: 706c6793500ab5a89ceec191519033263f2851c94fb707614b28c1c2da9fee89b274ee268bac880e8893a0f2ad4c24ee86d087894b4a9bec35fd28abe0200312
7
- data.tar.gz: a1156c538005d8cd01dfc3994c890a12cf872c4400b9c5e6e0ddcdd1e4d018ab9486edd3227b5c67718b643933258f6c009712e7c1c90b474cdc05c7d6e31a31
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
- RAILS_ENV=db_one rails console
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 = new(instance.config_filename)
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
- attr_reader :config_filename
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
- spec_klass = ActiveRecord::ConnectionAdapters::ConnectionSpecification
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 = spec_klass::Resolver.new(resolve_configs)
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
- @host_spec_cache = {}
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
- @host_spec_cache[host] = @db_spec_cache[k]
207
+ new_host_spec_cache[host] = new_db_spec_cache[k]
148
208
  end
149
209
  end
150
210
 
151
- @default_spec = spec_klass::Resolver.new(ActiveRecord::Base.configurations).spec(Rails.env.to_sym)
211
+ # Add the default hostnames as well
152
212
  ActiveRecord::Base.configurations[Rails.env]["host_names"].each do |host|
153
- @host_spec_cache[host] = @default_spec
213
+ new_host_spec_cache[host] = @default_spec
154
214
  end
155
215
 
156
- @default_connection_handler = ActiveRecord::Base.connection_handler
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
- @connection_handlers = {}
159
- @established_default = false
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
- if Rails::VERSION::MAJOR >= 5
324
- handler.establish_connection(spec.config)
325
- else
326
- handler.establish_connection(ActiveRecord::Base, spec)
327
- end
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
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  module RailsMultisite
2
3
  class Middleware
3
4
  def initialize(app, config = nil)
@@ -7,20 +7,28 @@ module RailsMultisite
7
7
  end
8
8
 
9
9
  initializer "RailsMultisite.init" do |app|
10
- Rails.configuration.multisite = false
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
- Rails.configuration.multisite = true
15
+ app.config.multisite = true
16
16
  Rails.logger.formatter = RailsMultisite::Formatter.new
17
- app.middleware.insert_after(ActionDispatch::Executor, RailsMultisite::Middleware)
18
- app.middleware.delete(ActionDispatch::Executor)
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
  #
3
3
  module RailsMultisite
4
- VERSION = "2.0.7"
4
+ VERSION = "2.3.0"
5
5
  end
@@ -1,3 +1,4 @@
1
+ # frozen_string_literal: true
1
2
  desc "migrate all sites in tier"
2
3
  task "multisite:migrate" => :environment do
3
4
  RailsMultisite::ConnectionManagement.each_connection do |db|
@@ -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.7
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: 2019-04-29 00:00:00.000000000 Z
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: '4.2'
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: '4.2'
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: '4.2'
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: '4.2'
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.3.0
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.0.3
88
+ rubygems_version: 3.1.2
89
89
  signing_key:
90
90
  specification_version: 4
91
91
  summary: Multi tenancy support for Rails