active_record_shards 3.6.4 → 3.7.0.rc1
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 +4 -4
- data/README.md +1 -2
- data/lib/active_record_shards-3-2.rb +11 -0
- data/lib/active_record_shards-4-0.rb +13 -0
- data/lib/active_record_shards-4-1.rb +13 -0
- data/lib/active_record_shards-5-0.rb +13 -0
- data/lib/active_record_shards.rb +18 -49
- data/lib/active_record_shards/connection_switcher-4-0.rb +67 -0
- data/lib/active_record_shards/connection_switcher-5-0.rb +26 -0
- data/lib/active_record_shards/connection_switcher.rb +10 -80
- data/lib/active_record_shards/default_slave_patches.rb +35 -31
- data/lib/active_record_shards/shard_selection.rb +54 -18
- data/lib/active_record_shards/tasks.rb +18 -5
- metadata +11 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4bcaab5398778bf85edcc00669416475575d3d13
|
4
|
+
data.tar.gz: 2515cabcc8ef1efcaacc8de48c2f67022b0b3dce
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5b3321dc11a00690d9ed4640270f5cc7655dbdb07aa4c0f6d8fcad30fe13414ecdb4487050f013c79ad3318ab74d1d5f836d2949263bae7c70a790337fbe891d
|
7
|
+
data.tar.gz: 00946bef3060ac8fefd1285d55dc53a4b2233f0c0dbe2f4d461256dcda9b1cd2a865ba0b1ae2aad5a562646d9c26c1a69c05ee00e217a9e605ec858ec62e3aa5
|
data/README.md
CHANGED
@@ -3,8 +3,7 @@
|
|
3
3
|
ActiveRecord Shards is an extension for ActiveRecord that provides support for sharded database and slaves. Basically it is just a nice way to
|
4
4
|
switch between database connections. We've made the implementation very small, and have tried not to reinvent any wheels already present in ActiveRecord.
|
5
5
|
|
6
|
-
ActiveRecord Shards has used and tested on Rails 3.2
|
7
|
-
more than a year.
|
6
|
+
ActiveRecord Shards has been used and tested on Rails 3.2, 4.0, 4.1, 4.2 and 5.0 and has in some form or another been used in production on a large Rails app for several years.
|
8
7
|
|
9
8
|
## Installation
|
10
9
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_record_shards/connection_pool'
|
3
|
+
require 'active_record_shards/connection_handler'
|
4
|
+
require 'active_record_shards/connection_specification'
|
5
|
+
|
6
|
+
|
7
|
+
ActiveRecordShards::ConnectionSpecification = ActiveRecord::Base::ConnectionSpecification
|
8
|
+
methods_to_override = [:remove_connection]
|
9
|
+
ActiveRecordShards.override_connection_handler_methods(methods_to_override)
|
10
|
+
|
11
|
+
ActiveRecord::Associations::Preloader::HasAndBelongsToMany.include(ActiveRecordShards::DefaultSlavePatches::HasAndBelongsToManyPreloaderPatches)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_record_shards/connection_pool'
|
3
|
+
require 'active_record_shards/connection_handler'
|
4
|
+
require 'active_record_shards/connection_specification'
|
5
|
+
require 'active_record_shards/schema_dumper_extension'
|
6
|
+
|
7
|
+
ActiveRecordShards::ConnectionSpecification = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
8
|
+
methods_to_override = [:establish_connection, :remove_connection, :pool_for, :pool_from_any_process_for]
|
9
|
+
ActiveRecordShards.override_connection_handler_methods(methods_to_override)
|
10
|
+
|
11
|
+
ActiveRecord::Associations::Preloader::HasAndBelongsToMany.include(ActiveRecordShards::DefaultSlavePatches::HasAndBelongsToManyPreloaderPatches)
|
12
|
+
|
13
|
+
ActiveRecord::SchemaDumper.prepend(ActiveRecordShards::SchemaDumperExtension)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
require 'active_record_shards/connection_pool'
|
3
|
+
require 'active_record_shards/connection_handler'
|
4
|
+
require 'active_record_shards/connection_specification'
|
5
|
+
require 'active_record_shards/schema_dumper_extension'
|
6
|
+
|
7
|
+
ActiveRecordShards::ConnectionSpecification = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
8
|
+
methods_to_override = [:establish_connection, :remove_connection, :pool_for, :pool_from_any_process_for]
|
9
|
+
ActiveRecordShards.override_connection_handler_methods(methods_to_override)
|
10
|
+
|
11
|
+
ActiveRecord::Associations::Builder::HasAndBelongsToMany.include(ActiveRecordShards::DefaultSlavePatches::Rails41HasAndBelongsToManyBuilderExtension)
|
12
|
+
|
13
|
+
ActiveRecord::SchemaDumper.prepend(ActiveRecordShards::SchemaDumperExtension)
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
|
4
|
+
|
5
|
+
require 'active_record_shards/schema_dumper_extension'
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
|
11
|
+
ActiveRecord::Associations::Builder::HasAndBelongsToMany.include(ActiveRecordShards::DefaultSlavePatches::Rails41HasAndBelongsToManyBuilderExtension)
|
12
|
+
|
13
|
+
ActiveRecord::SchemaDumper.prepend(ActiveRecordShards::SchemaDumperExtension)
|
data/lib/active_record_shards.rb
CHANGED
@@ -6,46 +6,8 @@ require 'active_record_shards/model'
|
|
6
6
|
require 'active_record_shards/shard_selection'
|
7
7
|
require 'active_record_shards/connection_switcher'
|
8
8
|
require 'active_record_shards/association_collection_connection_selection'
|
9
|
-
require 'active_record_shards/connection_pool'
|
10
9
|
require 'active_record_shards/migration'
|
11
10
|
require 'active_record_shards/default_slave_patches'
|
12
|
-
require 'active_record_shards/connection_handler'
|
13
|
-
require 'active_record_shards/connection_specification'
|
14
|
-
require 'active_record_shards/schema_dumper_extension'
|
15
|
-
|
16
|
-
if ActiveRecord::VERSION::MAJOR >= 4
|
17
|
-
methods_to_override = [:establish_connection, :remove_connection, :pool_for,
|
18
|
-
:pool_from_any_process_for]
|
19
|
-
ActiveRecordShards::ConnectionSpecification = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
20
|
-
else
|
21
|
-
methods_to_override = [:remove_connection]
|
22
|
-
ActiveRecordShards::ConnectionSpecification = ActiveRecord::Base::ConnectionSpecification
|
23
|
-
end
|
24
|
-
|
25
|
-
ActiveRecordShards.override_connection_handler_methods(methods_to_override)
|
26
|
-
|
27
|
-
ActiveRecord::Base.extend(ActiveRecordShards::ConfigurationParser)
|
28
|
-
ActiveRecord::Base.extend(ActiveRecordShards::Model)
|
29
|
-
ActiveRecord::Base.extend(ActiveRecordShards::ConnectionSwitcher)
|
30
|
-
ActiveRecord::Base.extend(ActiveRecordShards::DefaultSlavePatches)
|
31
|
-
|
32
|
-
if ActiveRecord.const_defined?(:Relation)
|
33
|
-
ActiveRecord::Relation.send(:include, ActiveRecordShards::DefaultSlavePatches::ActiveRelationPatches)
|
34
|
-
end
|
35
|
-
|
36
|
-
if ActiveRecord::Associations.const_defined?(:Preloader) && ActiveRecord::Associations::Preloader.const_defined?(:HasAndBelongsToMany)
|
37
|
-
ActiveRecord::Associations::Preloader::HasAndBelongsToMany.send(:include, ActiveRecordShards::DefaultSlavePatches::HasAndBelongsToManyPreloaderPatches)
|
38
|
-
end
|
39
|
-
|
40
|
-
if ActiveRecord::VERSION::STRING >= '4.1.0'
|
41
|
-
ActiveRecord::Associations::Builder::HasAndBelongsToMany.send(:include, ActiveRecordShards::DefaultSlavePatches::Rails41HasAndBelongsToManyBuilderExtension)
|
42
|
-
end
|
43
|
-
|
44
|
-
ActiveRecord::Associations::CollectionProxy.send(:include, ActiveRecordShards::AssociationCollectionConnectionSelection)
|
45
|
-
|
46
|
-
if ActiveRecord::VERSION::MAJOR >= 4
|
47
|
-
ActiveRecord::SchemaDumper.send(:prepend, ActiveRecordShards::SchemaDumperExtension)
|
48
|
-
end
|
49
11
|
|
50
12
|
module ActiveRecordShards
|
51
13
|
def self.rails_env
|
@@ -56,15 +18,22 @@ module ActiveRecordShards
|
|
56
18
|
end
|
57
19
|
end
|
58
20
|
|
59
|
-
ActiveRecord::Base.
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
21
|
+
ActiveRecord::Base.extend(ActiveRecordShards::ConfigurationParser)
|
22
|
+
ActiveRecord::Base.extend(ActiveRecordShards::Model)
|
23
|
+
ActiveRecord::Base.extend(ActiveRecordShards::ConnectionSwitcher)
|
24
|
+
ActiveRecord::Base.extend(ActiveRecordShards::DefaultSlavePatches)
|
25
|
+
ActiveRecord::Relation.include(ActiveRecordShards::DefaultSlavePatches::ActiveRelationPatches)
|
26
|
+
ActiveRecord::Associations::CollectionProxy.include(ActiveRecordShards::AssociationCollectionConnectionSelection)
|
27
|
+
|
28
|
+
case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
|
29
|
+
when '3.2'
|
30
|
+
require 'active_record_shards-3-2'
|
31
|
+
when '4.0'
|
32
|
+
require 'active_record_shards-4-0'
|
33
|
+
when '4.1', '4.2'
|
34
|
+
require 'active_record_shards-4-1'
|
35
|
+
when '5.0'
|
36
|
+
require 'active_record_shards-5-0'
|
37
|
+
else
|
38
|
+
raise "ActiveRecordShards is not compatible with #{ActiveRecord::VERSION::STRING}"
|
70
39
|
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module ActiveRecordShards
|
2
|
+
module ConnectionSwitcher
|
3
|
+
|
4
|
+
# Name of the connection pool. Used by ConnectionHandler to retrieve the current connection pool.
|
5
|
+
def connection_pool_name # :nodoc:
|
6
|
+
name = current_shard_selection.shard_name(self)
|
7
|
+
|
8
|
+
if configurations[name].nil? && on_slave?
|
9
|
+
current_shard_selection.shard_name(self, false)
|
10
|
+
else
|
11
|
+
name
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def ensure_shard_connection
|
18
|
+
establish_shard_connection unless connected_to_shard?
|
19
|
+
end
|
20
|
+
|
21
|
+
def establish_shard_connection
|
22
|
+
name = connection_pool_name
|
23
|
+
spec = configurations[name]
|
24
|
+
|
25
|
+
raise ActiveRecord::AdapterNotSpecified.new("No database defined by #{name} in database.yml") if spec.nil?
|
26
|
+
|
27
|
+
# in 3.2 rails is asking for a connection pool in a map of these ConnectionSpecifications. If we want to re-use connections,
|
28
|
+
# we need to re-use specs.
|
29
|
+
|
30
|
+
# note that since we're subverting the standard establish_connection path, we have to handle the funky autoloading of the
|
31
|
+
# connection adapter ourselves.
|
32
|
+
specification_cache[name] ||= begin
|
33
|
+
if ActiveRecord::VERSION::STRING >= '4.1.0'
|
34
|
+
resolver = ActiveRecordShards::ConnectionSpecification::Resolver.new configurations
|
35
|
+
resolver.spec(spec)
|
36
|
+
else
|
37
|
+
resolver = ActiveRecordShards::ConnectionSpecification::Resolver.new spec, configurations
|
38
|
+
resolver.spec
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
43
|
+
connection_handler.establish_connection(self, specification_cache[name])
|
44
|
+
else
|
45
|
+
connection_handler.establish_connection(connection_pool_name, specification_cache[name])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def specification_cache
|
50
|
+
@@specification_cache ||= {}
|
51
|
+
end
|
52
|
+
|
53
|
+
def connection_pool_key
|
54
|
+
specification_cache[connection_pool_name]
|
55
|
+
end
|
56
|
+
|
57
|
+
def connected_to_shard?
|
58
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
59
|
+
specs_to_pools = Hash[connection_handler.connection_pool_list.map { |pool| [pool.spec, pool] }]
|
60
|
+
else
|
61
|
+
specs_to_pools = connection_handler.connection_pools
|
62
|
+
end
|
63
|
+
|
64
|
+
specs_to_pools.has_key?(connection_pool_key)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module ActiveRecordShards
|
2
|
+
module ConnectionSwitcher
|
3
|
+
def connection_specification_name
|
4
|
+
name = current_shard_selection.resolve_connection_name(sharded: is_sharded?, configurations: self.configurations)
|
5
|
+
|
6
|
+
raise "No configuration found for #{name}" unless configurations[name] || name == "primary"
|
7
|
+
name
|
8
|
+
end
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def ensure_shard_connection
|
13
|
+
# See if we've connected before. If not, call `#establish_connection`
|
14
|
+
# so that ActiveRecord can resolve connection_specification_name to an
|
15
|
+
# ARS connection.
|
16
|
+
spec_name = connection_specification_name
|
17
|
+
|
18
|
+
pool = connection_handler.retrieve_connection_pool(spec_name)
|
19
|
+
if pool.nil?
|
20
|
+
resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new configurations
|
21
|
+
spec = resolver.spec(spec_name.to_sym, spec_name)
|
22
|
+
connection_handler.establish_connection spec
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -114,22 +114,6 @@ module ActiveRecordShards
|
|
114
114
|
switch_connection(old_options)
|
115
115
|
end
|
116
116
|
|
117
|
-
# Name of the connection pool. Used by ConnectionHandler to retrieve the current connection pool.
|
118
|
-
def connection_pool_name # :nodoc:
|
119
|
-
name = @connection_pool_name_override || current_shard_selection.shard_name(self)
|
120
|
-
|
121
|
-
if configurations[name].nil? && on_slave?
|
122
|
-
current_shard_selection.shard_name(self, false)
|
123
|
-
else
|
124
|
-
name
|
125
|
-
end
|
126
|
-
end
|
127
|
-
|
128
|
-
def establish_connection_override(connection_name)
|
129
|
-
@connection_pool_name_override = connection_name
|
130
|
-
establish_connection(connection_name)
|
131
|
-
end
|
132
|
-
|
133
117
|
def supports_sharding?
|
134
118
|
shard_names.any?
|
135
119
|
end
|
@@ -165,7 +149,7 @@ module ActiveRecordShards
|
|
165
149
|
current_shard_selection.shard = options[:shard]
|
166
150
|
end
|
167
151
|
|
168
|
-
|
152
|
+
ensure_shard_connection
|
169
153
|
end
|
170
154
|
end
|
171
155
|
|
@@ -173,52 +157,6 @@ module ActiveRecordShards
|
|
173
157
|
ActiveRecordShards.rails_env
|
174
158
|
end
|
175
159
|
|
176
|
-
def establish_shard_connection
|
177
|
-
name = connection_pool_name
|
178
|
-
spec = configurations[name]
|
179
|
-
|
180
|
-
raise ActiveRecord::AdapterNotSpecified.new("No database defined by #{name} in database.yml") if spec.nil?
|
181
|
-
|
182
|
-
# in 3.2 rails is asking for a connection pool in a map of these ConnectionSpecifications. If we want to re-use connections,
|
183
|
-
# we need to re-use specs.
|
184
|
-
|
185
|
-
# note that since we're subverting the standard establish_connection path, we have to handle the funky autoloading of the
|
186
|
-
# connection adapter ourselves.
|
187
|
-
specification_cache[name] ||= begin
|
188
|
-
if ActiveRecord::VERSION::STRING >= '4.1.0'
|
189
|
-
resolver = ActiveRecordShards::ConnectionSpecification::Resolver.new configurations
|
190
|
-
resolver.spec(spec)
|
191
|
-
else
|
192
|
-
resolver = ActiveRecordShards::ConnectionSpecification::Resolver.new spec, configurations
|
193
|
-
resolver.spec
|
194
|
-
end
|
195
|
-
end
|
196
|
-
|
197
|
-
if ActiveRecord::VERSION::MAJOR >= 4
|
198
|
-
connection_handler.establish_connection(self, specification_cache[name])
|
199
|
-
else
|
200
|
-
connection_handler.establish_connection(connection_pool_name, specification_cache[name])
|
201
|
-
end
|
202
|
-
end
|
203
|
-
|
204
|
-
def specification_cache
|
205
|
-
@@specification_cache ||= {}
|
206
|
-
end
|
207
|
-
|
208
|
-
def connection_pool_key
|
209
|
-
specification_cache[connection_pool_name]
|
210
|
-
end
|
211
|
-
|
212
|
-
def connected_to_shard?
|
213
|
-
if ActiveRecord::VERSION::MAJOR >= 4
|
214
|
-
specs_to_pools = Hash[connection_handler.connection_pool_list.map { |pool| [pool.spec, pool] }]
|
215
|
-
else
|
216
|
-
specs_to_pools = connection_handler.connection_pools
|
217
|
-
end
|
218
|
-
|
219
|
-
specs_to_pools.has_key?(connection_pool_key)
|
220
|
-
end
|
221
|
-
|
222
160
|
def columns_with_default_shard
|
223
161
|
if is_sharded? && current_shard_id.nil? && table_name != ActiveRecord::Migrator.schema_migrations_table_name
|
224
162
|
on_first_shard { columns_without_default_shard }
|
@@ -237,23 +175,6 @@ module ActiveRecordShards
|
|
237
175
|
result
|
238
176
|
end
|
239
177
|
|
240
|
-
def autoload_adapter(adapter_name)
|
241
|
-
begin
|
242
|
-
gem "activerecord-#{adapter_name}-adapter"
|
243
|
-
require "active_record/connection_adapters/#{adapter_name}_adapter"
|
244
|
-
rescue LoadError
|
245
|
-
begin
|
246
|
-
require "active_record/connection_adapters/#{adapter_name}_adapter"
|
247
|
-
rescue LoadError
|
248
|
-
raise "Please install the #{adapter_name} adapter: `gem install activerecord-#{adapter_name}-adapter` (#{$!})"
|
249
|
-
end
|
250
|
-
end
|
251
|
-
|
252
|
-
if !ActiveRecord::Base.respond_to?(adapter_name + "_connection")
|
253
|
-
raise AdapterNotFound, "database configuration specifies nonexistent #{adapter_name} adapter"
|
254
|
-
end
|
255
|
-
end
|
256
|
-
|
257
178
|
class MasterSlaveProxy
|
258
179
|
def initialize(target, which)
|
259
180
|
@target = target
|
@@ -266,3 +187,12 @@ module ActiveRecordShards
|
|
266
187
|
end
|
267
188
|
end
|
268
189
|
end
|
190
|
+
|
191
|
+
case "#{ActiveRecord::VERSION::MAJOR}.#{ActiveRecord::VERSION::MINOR}"
|
192
|
+
when '3.2', '4.0', '4.1', '4.2'
|
193
|
+
require 'active_record_shards/connection_switcher-4-0'
|
194
|
+
when '5.0'
|
195
|
+
require 'active_record_shards/connection_switcher-5-0'
|
196
|
+
else
|
197
|
+
raise "ActiveRecordShards is not compatible with #{ActiveRecord::VERSION::STRING}"
|
198
|
+
end
|
@@ -24,50 +24,54 @@ module ActiveRecordShards
|
|
24
24
|
RUBY
|
25
25
|
end
|
26
26
|
|
27
|
+
def columns_with_default_slave(*args, &block)
|
28
|
+
read_columns_from = if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
|
29
|
+
:slave
|
30
|
+
else
|
31
|
+
:master
|
32
|
+
end
|
33
|
+
|
34
|
+
on_cx_switch_block(read_columns_from, :construct_ro_scope => false) { columns_without_default_slave(*args, &block) }
|
35
|
+
end
|
36
|
+
|
37
|
+
def transaction_with_slave_off(*args, &block)
|
38
|
+
if on_slave_by_default?
|
39
|
+
old_val = Thread.current[:_active_record_shards_slave_off]
|
40
|
+
Thread.current[:_active_record_shards_slave_off] = true
|
41
|
+
end
|
42
|
+
|
43
|
+
transaction_without_slave_off(*args, &block)
|
44
|
+
ensure
|
45
|
+
if on_slave_by_default?
|
46
|
+
Thread.current[:_active_record_shards_slave_off] = old_val
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module InstanceMethods
|
51
|
+
# fix ActiveRecord to do the right thing, and use our aliased quote_value
|
52
|
+
def quote_value(*args, &block)
|
53
|
+
self.class.quote_value(*args, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
def reload_with_slave_off(*args, &block)
|
57
|
+
self.class.on_master { reload_without_slave_off(*args, &block) }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
27
61
|
CLASS_SLAVE_METHODS = [ :find_by_sql, :count_by_sql, :calculate, :find_one, :find_some, :find_every, :exists?, :table_exists? ]
|
28
62
|
|
29
63
|
def self.extended(base)
|
30
64
|
CLASS_SLAVE_METHODS.each { |m| ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(true, base, m) }
|
31
65
|
|
32
66
|
base.class_eval do
|
33
|
-
|
34
|
-
def quote_value(*args, &block)
|
35
|
-
self.class.quote_value(*args, &block)
|
36
|
-
end
|
67
|
+
include InstanceMethods
|
37
68
|
|
38
|
-
def reload_with_slave_off(*args, &block)
|
39
|
-
self.class.on_master { reload_without_slave_off(*args, &block) }
|
40
|
-
end
|
41
69
|
alias_method :reload_without_slave_off, :reload
|
42
70
|
alias_method :reload, :reload_with_slave_off
|
43
71
|
|
44
72
|
class << self
|
45
|
-
def columns_with_default_slave(*args, &block)
|
46
|
-
read_columns_from = if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
|
47
|
-
:slave
|
48
|
-
else
|
49
|
-
:master
|
50
|
-
end
|
51
|
-
|
52
|
-
on_cx_switch_block(read_columns_from, :construct_ro_scope => false) { columns_without_default_slave(*args, &block) }
|
53
|
-
end
|
54
73
|
alias_method :columns_without_default_slave, :columns
|
55
74
|
alias_method :columns, :columns_with_default_slave
|
56
|
-
end
|
57
|
-
|
58
|
-
class << self
|
59
|
-
def transaction_with_slave_off(*args, &block)
|
60
|
-
if on_slave_by_default?
|
61
|
-
old_val = Thread.current[:_active_record_shards_slave_off]
|
62
|
-
Thread.current[:_active_record_shards_slave_off] = true
|
63
|
-
end
|
64
|
-
|
65
|
-
transaction_without_slave_off(*args, &block)
|
66
|
-
ensure
|
67
|
-
if on_slave_by_default?
|
68
|
-
Thread.current[:_active_record_shards_slave_off] = old_val
|
69
|
-
end
|
70
|
-
end
|
71
75
|
|
72
76
|
alias_method :transaction_without_slave_off, :transaction
|
73
77
|
alias_method :transaction, :transaction_with_slave_off
|
@@ -8,14 +8,65 @@ module ActiveRecordShards
|
|
8
8
|
@on_slave = false
|
9
9
|
end
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
if ActiveRecord::VERSION::MAJOR < 5
|
12
|
+
|
13
|
+
def shard(klass = nil)
|
14
|
+
if (@shard || self.class.default_shard) && (klass.nil? || klass.is_sharded?)
|
15
|
+
if @shard == NO_SHARD
|
16
|
+
nil
|
17
|
+
else
|
18
|
+
@shard || self.class.default_shard
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def shard_name(klass = nil, try_slave = true)
|
24
|
+
the_shard = shard(klass)
|
25
|
+
|
26
|
+
@shard_names ||= {}
|
27
|
+
@shard_names[ActiveRecordShards.rails_env] ||= {}
|
28
|
+
@shard_names[ActiveRecordShards.rails_env][the_shard] ||= {}
|
29
|
+
@shard_names[ActiveRecordShards.rails_env][the_shard][try_slave] ||= {}
|
30
|
+
@shard_names[ActiveRecordShards.rails_env][the_shard][try_slave][@on_slave] ||= begin
|
31
|
+
s = ActiveRecordShards.rails_env.dup
|
32
|
+
s << "_shard_#{the_shard}" if the_shard
|
33
|
+
s << "_slave" if @on_slave && try_slave
|
34
|
+
s
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
else
|
39
|
+
|
40
|
+
def shard
|
41
|
+
if @shard.nil? || @shard == NO_SHARD
|
14
42
|
nil
|
15
43
|
else
|
16
44
|
@shard || self.class.default_shard
|
17
45
|
end
|
18
46
|
end
|
47
|
+
|
48
|
+
PRIMARY = "primary".freeze
|
49
|
+
def resolve_connection_name(sharded:, configurations:)
|
50
|
+
resolved_shard = sharded ? shard : nil
|
51
|
+
|
52
|
+
if !resolved_shard && !@on_slave
|
53
|
+
return PRIMARY
|
54
|
+
end
|
55
|
+
|
56
|
+
@shard_names ||= {}
|
57
|
+
@shard_names[ActiveRecordShards.rails_env] ||= {}
|
58
|
+
@shard_names[ActiveRecordShards.rails_env][resolved_shard] ||= {}
|
59
|
+
@shard_names[ActiveRecordShards.rails_env][resolved_shard][@on_slave] ||= begin
|
60
|
+
s = ActiveRecordShards.rails_env.dup
|
61
|
+
s << "_shard_#{resolved_shard}" if resolved_shard
|
62
|
+
|
63
|
+
if @on_slave && configurations["#{s}_slave"] # fall back to master connection
|
64
|
+
s << "_slave"
|
65
|
+
end
|
66
|
+
s
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
19
70
|
end
|
20
71
|
|
21
72
|
def shard=(new_shard)
|
@@ -30,21 +81,6 @@ module ActiveRecordShards
|
|
30
81
|
@on_slave = (new_slave == true)
|
31
82
|
end
|
32
83
|
|
33
|
-
def shard_name(klass = nil, try_slave = true)
|
34
|
-
the_shard = shard(klass)
|
35
|
-
|
36
|
-
@shard_names ||= {}
|
37
|
-
@shard_names[ActiveRecordShards.rails_env] ||= {}
|
38
|
-
@shard_names[ActiveRecordShards.rails_env][the_shard] ||= {}
|
39
|
-
@shard_names[ActiveRecordShards.rails_env][the_shard][try_slave] ||= {}
|
40
|
-
@shard_names[ActiveRecordShards.rails_env][the_shard][try_slave][@on_slave] ||= begin
|
41
|
-
s = ActiveRecordShards.rails_env.dup
|
42
|
-
s << "_shard_#{the_shard}" if the_shard
|
43
|
-
s << "_slave" if @on_slave && try_slave
|
44
|
-
s
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
84
|
def options
|
49
85
|
{:shard => @shard, :slave => @on_slave}
|
50
86
|
end
|
@@ -12,8 +12,11 @@ namespace :db do
|
|
12
12
|
if key.starts_with?(ActiveRecordShards.rails_env) && !key.ends_with?("_slave")
|
13
13
|
begin
|
14
14
|
ActiveRecordShards::Tasks.root_connection(conf).drop_database(conf['database'])
|
15
|
-
rescue
|
16
|
-
|
15
|
+
# rescue ActiveRecord::NoDatabaseError # TODO: exists in AR but never is raised here ...
|
16
|
+
# $stderr.puts "Database '#{conf['database']}' does not exist"
|
17
|
+
rescue Exception => error
|
18
|
+
$stderr.puts error, *(error.backtrace)
|
19
|
+
$stderr.puts "Couldn't drop #{conf['database']}"
|
17
20
|
end
|
18
21
|
end
|
19
22
|
end
|
@@ -48,7 +51,7 @@ namespace :db do
|
|
48
51
|
end
|
49
52
|
end
|
50
53
|
end
|
51
|
-
ActiveRecord::Base.establish_connection(ActiveRecordShards.rails_env)
|
54
|
+
ActiveRecord::Base.establish_connection(ActiveRecordShards.rails_env.to_sym)
|
52
55
|
end
|
53
56
|
|
54
57
|
desc "Raises an error if there are pending migrations"
|
@@ -87,8 +90,18 @@ end
|
|
87
90
|
|
88
91
|
module ActiveRecordShards
|
89
92
|
module Tasks
|
90
|
-
|
91
|
-
|
93
|
+
if ActiveRecord::VERSION::MAJOR < 5
|
94
|
+
def self.root_connection(conf)
|
95
|
+
ActiveRecord::Base.send("#{conf['adapter']}_connection", conf.merge('database' => nil))
|
96
|
+
end
|
97
|
+
else
|
98
|
+
def self.root_connection(conf)
|
99
|
+
# this will trigger rails to load the adapter
|
100
|
+
conf = conf.merge('database' => nil)
|
101
|
+
resolver = ActiveRecord::ConnectionAdapters::ConnectionSpecification::Resolver.new(ActiveRecord::Base.configurations)
|
102
|
+
resolver.spec(conf)
|
103
|
+
ActiveRecord::Base.send("#{conf['adapter']}_connection", conf)
|
104
|
+
end
|
92
105
|
end
|
93
106
|
end
|
94
107
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_record_shards
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.7.0.rc1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mick Staugaard
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2016-
|
13
|
+
date: 2016-08-01 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -174,12 +174,18 @@ extensions: []
|
|
174
174
|
extra_rdoc_files: []
|
175
175
|
files:
|
176
176
|
- README.md
|
177
|
+
- lib/active_record_shards-3-2.rb
|
178
|
+
- lib/active_record_shards-4-0.rb
|
179
|
+
- lib/active_record_shards-4-1.rb
|
180
|
+
- lib/active_record_shards-5-0.rb
|
177
181
|
- lib/active_record_shards.rb
|
178
182
|
- lib/active_record_shards/association_collection_connection_selection.rb
|
179
183
|
- lib/active_record_shards/configuration_parser.rb
|
180
184
|
- lib/active_record_shards/connection_handler.rb
|
181
185
|
- lib/active_record_shards/connection_pool.rb
|
182
186
|
- lib/active_record_shards/connection_specification.rb
|
187
|
+
- lib/active_record_shards/connection_switcher-4-0.rb
|
188
|
+
- lib/active_record_shards/connection_switcher-5-0.rb
|
183
189
|
- lib/active_record_shards/connection_switcher.rb
|
184
190
|
- lib/active_record_shards/default_slave_patches.rb
|
185
191
|
- lib/active_record_shards/migration.rb
|
@@ -203,12 +209,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
203
209
|
version: '2.0'
|
204
210
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
205
211
|
requirements:
|
206
|
-
- - "
|
212
|
+
- - ">"
|
207
213
|
- !ruby/object:Gem::Version
|
208
|
-
version:
|
214
|
+
version: 1.3.1
|
209
215
|
requirements: []
|
210
216
|
rubyforge_project:
|
211
|
-
rubygems_version: 2.
|
217
|
+
rubygems_version: 2.6.6
|
212
218
|
signing_key:
|
213
219
|
specification_version: 4
|
214
220
|
summary: Simple database switching for ActiveRecord.
|