active_record_shards 3.6.4 → 3.7.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|