active_record_shards 3.6.0 → 3.6.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 +4 -4
- data/lib/active_record_shards.rb +12 -12
- data/lib/active_record_shards/configuration_parser.rb +6 -5
- data/lib/active_record_shards/connection_pool.rb +13 -11
- data/lib/active_record_shards/connection_switcher.rb +23 -21
- data/lib/active_record_shards/default_slave_patches.rb +66 -48
- data/lib/active_record_shards/migration.rb +18 -20
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1dd69ed02637e49d444f17f46112f4353bd38274
|
4
|
+
data.tar.gz: 72b1d921a77e347f093d0591b46a4c0dd088cb4e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 25977dee6f8cd3188d6e7577c987a86c30e22b0ac2ee327dd9dccb07fb38bbe925c138497fc15caa1252fe6320cf849740d208abf09a04f8ee0deee2a654adf6
|
7
|
+
data.tar.gz: 000d3325d3934d6b3c4655860edfe512970a0eceac91236dc4064eb9fa5775652df3e283bba0fb232b18c08a40eaada26c1c66b93d3344e70193b971da7e3b59
|
data/lib/active_record_shards.rb
CHANGED
@@ -33,11 +33,11 @@ if ActiveRecord.const_defined?(:Relation)
|
|
33
33
|
end
|
34
34
|
|
35
35
|
if ActiveRecord::Associations.const_defined?(:Preloader) && ActiveRecord::Associations::Preloader.const_defined?(:HasAndBelongsToMany)
|
36
|
-
ActiveRecord::Associations::Preloader::HasAndBelongsToMany.send(:
|
36
|
+
ActiveRecord::Associations::Preloader::HasAndBelongsToMany.send(:include, ActiveRecordShards::DefaultSlavePatches::HasAndBelongsToManyPreloaderPatches)
|
37
37
|
end
|
38
38
|
|
39
39
|
if ActiveRecord::VERSION::STRING >= '4.1.0'
|
40
|
-
ActiveRecord::Associations::Builder::HasAndBelongsToMany.send(:
|
40
|
+
ActiveRecord::Associations::Builder::HasAndBelongsToMany.send(:include, ActiveRecordShards::DefaultSlavePatches::Rails41HasAndBelongsToManyBuilderExtension)
|
41
41
|
end
|
42
42
|
|
43
43
|
ActiveRecord::Associations::CollectionProxy.send(:include, ActiveRecordShards::AssociationCollectionConnectionSelection)
|
@@ -53,17 +53,17 @@ module ActiveRecordShards
|
|
53
53
|
env ||= ENV['RAILS_ENV']
|
54
54
|
env ||= 'development'
|
55
55
|
end
|
56
|
+
end
|
56
57
|
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
end
|
58
|
+
ActiveRecord::Base.singleton_class.class_eval do
|
59
|
+
def establish_connection_with_connection_pool_name(spec = nil)
|
60
|
+
case spec
|
61
|
+
when ActiveRecordShards::ConnectionSpecification
|
62
|
+
connection_handler.establish_connection(connection_pool_name, spec)
|
63
|
+
else
|
64
|
+
establish_connection_without_connection_pool_name(spec)
|
65
65
|
end
|
66
66
|
end
|
67
|
+
alias_method :establish_connection_without_connection_pool_name, :establish_connection
|
68
|
+
alias_method :establish_connection, :establish_connection_with_connection_pool_name
|
67
69
|
end
|
68
|
-
|
69
|
-
ActiveRecord::Base.singleton_class.send(:prepend, ActiveRecordShards::ActiveRecordConnectionPoolName)
|
@@ -35,14 +35,15 @@ module ActiveRecordShards
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
super(explode(conf))
|
41
|
-
end
|
38
|
+
def configurations_with_shard_explosion=(conf)
|
39
|
+
self.configurations_without_shard_explosion = explode(conf)
|
42
40
|
end
|
43
41
|
|
44
42
|
def ConfigurationParser.extended(klass)
|
45
|
-
klass.singleton_class.send(:
|
43
|
+
klass.singleton_class.send(:alias_method, :configurations_without_shard_explosion=, :configurations=)
|
44
|
+
klass.singleton_class.send(:alias_method, :configurations=, :configurations_with_shard_explosion=)
|
45
|
+
klass.singleton_class.send(:public, :configurations=)
|
46
|
+
|
46
47
|
klass.configurations = klass.configurations if klass.configurations.present?
|
47
48
|
end
|
48
49
|
end
|
@@ -13,20 +13,22 @@ module ActiveRecordShards
|
|
13
13
|
# ActiveRecordShards.override_connection_handler_methods(methods_to_override)
|
14
14
|
#
|
15
15
|
def self.override_connection_handler_methods(method_names)
|
16
|
-
injected_module = Module.new
|
17
16
|
method_names.each do |method_name|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
17
|
+
ActiveRecord::ConnectionAdapters::ConnectionHandler.class_eval do
|
18
|
+
define_method("#{method_name}_with_connection_pool_name") do |*args|
|
19
|
+
unless args[0].is_a? ConnectionPoolNameDecorator
|
20
|
+
name = if args[0].is_a? String
|
21
|
+
args[0]
|
22
|
+
else
|
23
|
+
args[0].connection_pool_name
|
24
|
+
end
|
25
|
+
args[0] = ConnectionPoolNameDecorator.new(name)
|
26
|
+
end
|
27
|
+
send("#{method_name}_without_connection_pool_name", *args)
|
26
28
|
end
|
27
|
-
|
29
|
+
alias_method :"#{method_name}_without_connection_pool_name", method_name
|
30
|
+
alias_method method_name, :"#{method_name}_with_connection_pool_name"
|
28
31
|
end
|
29
32
|
end
|
30
|
-
ActiveRecord::ConnectionAdapters::ConnectionHandler.send(:prepend, injected_module)
|
31
33
|
end
|
32
34
|
end
|
@@ -4,28 +4,12 @@ module ActiveRecordShards
|
|
4
4
|
module ConnectionSwitcher
|
5
5
|
SHARD_NAMES_CONFIG_KEY = 'shard_names'.freeze
|
6
6
|
|
7
|
-
module PrependMethods
|
8
|
-
def columns
|
9
|
-
if is_sharded? && current_shard_id.nil? && table_name != ActiveRecord::Migrator.schema_migrations_table_name
|
10
|
-
on_first_shard { super }
|
11
|
-
else
|
12
|
-
super
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
def table_exists?
|
17
|
-
result = super()
|
18
|
-
|
19
|
-
if !result && is_sharded? && (shard_name = shard_names.first)
|
20
|
-
result = on_shard(shard_name) { super }
|
21
|
-
end
|
22
|
-
|
23
|
-
result
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
7
|
def self.extended(klass)
|
28
|
-
klass.singleton_class.send(:
|
8
|
+
klass.singleton_class.send(:alias_method, :columns_without_default_shard, :columns)
|
9
|
+
klass.singleton_class.send(:alias_method, :columns, :columns_with_default_shard)
|
10
|
+
|
11
|
+
klass.singleton_class.send(:alias_method, :table_exists_without_default_shard?, :table_exists?)
|
12
|
+
klass.singleton_class.send(:alias_method, :table_exists?, :table_exists_with_default_shard?)
|
29
13
|
end
|
30
14
|
|
31
15
|
def default_shard=(new_default_shard)
|
@@ -234,6 +218,24 @@ module ActiveRecordShards
|
|
234
218
|
specs_to_pools.has_key?(connection_pool_key)
|
235
219
|
end
|
236
220
|
|
221
|
+
def columns_with_default_shard
|
222
|
+
if is_sharded? && current_shard_id.nil? && table_name != ActiveRecord::Migrator.schema_migrations_table_name
|
223
|
+
on_first_shard { columns_without_default_shard }
|
224
|
+
else
|
225
|
+
columns_without_default_shard
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
def table_exists_with_default_shard?
|
230
|
+
result = table_exists_without_default_shard?
|
231
|
+
|
232
|
+
if !result && is_sharded? && (shard_name = shard_names.first)
|
233
|
+
result = on_shard(shard_name) { table_exists_without_default_shard? }
|
234
|
+
end
|
235
|
+
|
236
|
+
result
|
237
|
+
end
|
238
|
+
|
237
239
|
def autoload_adapter(adapter_name)
|
238
240
|
begin
|
239
241
|
require 'rubygems'
|
@@ -9,59 +9,70 @@ module ActiveRecordShards
|
|
9
9
|
end
|
10
10
|
|
11
11
|
return unless base_methods.include?(method)
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
_, method, punctuation = method.to_s.match(/^(.*?)([\?\!]?)$/).to_a
|
13
|
+
base.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
14
|
+
#{class_method ? "class << self" : ""}
|
15
|
+
def #{method}_with_default_slave#{punctuation}(*args, &block)
|
16
|
+
on_slave_unless_tx do
|
17
|
+
#{method}_without_default_slave#{punctuation}(*args, &block)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
alias_method :#{method}_without_default_slave#{punctuation}, :#{method}#{punctuation}
|
22
|
+
alias_method :#{method}#{punctuation}, :#{method}_with_default_slave#{punctuation}
|
23
|
+
#{class_method ? "end" : ""}
|
24
|
+
RUBY
|
19
25
|
end
|
20
26
|
|
21
27
|
CLASS_SLAVE_METHODS = [ :find_by_sql, :count_by_sql, :calculate, :find_one, :find_some, :find_every, :quote_value, :sanitize_sql_hash_for_conditions, :exists?, :table_exists? ]
|
22
28
|
|
23
|
-
|
24
|
-
|
25
|
-
if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
|
26
|
-
read_columns_from = :slave
|
27
|
-
else
|
28
|
-
read_columns_form = :master
|
29
|
-
end
|
30
|
-
|
31
|
-
on_cx_switch_block(read_columns_from, construct_ro_scope: false) { super }
|
32
|
-
end
|
29
|
+
def self.extended(base)
|
30
|
+
CLASS_SLAVE_METHODS.each { |m| ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(true, base, m) }
|
33
31
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
32
|
+
base.class_eval do
|
33
|
+
# fix ActiveRecord to do the right thing, and use our aliased quote_value
|
34
|
+
def quote_value(*args, &block)
|
35
|
+
self.class.quote_value(*args, &block)
|
38
36
|
end
|
39
37
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
38
|
+
def reload_with_slave_off(*args, &block)
|
39
|
+
self.class.on_master { reload_without_slave_off(*args, &block) }
|
40
|
+
end
|
41
|
+
alias_method :reload_without_slave_off, :reload
|
42
|
+
alias_method :reload, :reload_with_slave_off
|
43
|
+
|
44
|
+
class << self
|
45
|
+
def columns_with_default_slave(*args, &block)
|
46
|
+
if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
|
47
|
+
read_columns_from = :slave
|
48
|
+
else
|
49
|
+
read_columns_form = :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
|
+
alias_method :columns_without_default_slave, :columns
|
55
|
+
alias_method :columns, :columns_with_default_slave
|
44
56
|
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
module PrependMethods
|
49
|
-
# fix ActiveRecord to do the right thing, and use our aliased quote_value
|
50
|
-
def quote_value(*args, &block)
|
51
|
-
self.class.quote_value(*args, &block)
|
52
|
-
end
|
53
57
|
|
54
|
-
|
55
|
-
|
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
|
+
|
72
|
+
alias_method :transaction_without_slave_off, :transaction
|
73
|
+
alias_method :transaction, :transaction_with_slave_off
|
74
|
+
end
|
56
75
|
end
|
57
|
-
end
|
58
|
-
|
59
|
-
def self.extended(base)
|
60
|
-
base.send(:prepend, PrependMethods)
|
61
|
-
base.singleton_class.send(:prepend, PrependClassMethods)
|
62
|
-
|
63
|
-
CLASS_SLAVE_METHODS.each { |m| ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(true, base, m) }
|
64
|
-
|
65
76
|
if ActiveRecord::Associations.const_defined?(:HasAndBelongsToManyAssociation)
|
66
77
|
ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, ActiveRecord::Associations::HasAndBelongsToManyAssociation, :construct_sql)
|
67
78
|
ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, ActiveRecord::Associations::HasAndBelongsToManyAssociation, :construct_find_options!)
|
@@ -89,7 +100,7 @@ module ActiveRecordShards
|
|
89
100
|
end
|
90
101
|
|
91
102
|
module HasAndBelongsToManyPreloaderPatches
|
92
|
-
def self.
|
103
|
+
def self.included(base)
|
93
104
|
ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, base, :records_for) rescue nil
|
94
105
|
end
|
95
106
|
|
@@ -97,8 +108,8 @@ module ActiveRecordShards
|
|
97
108
|
klass.on_slave_unless_tx { yield }
|
98
109
|
end
|
99
110
|
|
100
|
-
def
|
101
|
-
on_slave_unless_tx {
|
111
|
+
def exists_with_default_slave?(*args, &block)
|
112
|
+
on_slave_unless_tx { exists_without_default_slave?(*args, &block) }
|
102
113
|
end
|
103
114
|
end
|
104
115
|
|
@@ -106,8 +117,15 @@ module ActiveRecordShards
|
|
106
117
|
# this simplifies the hell out of our existence, because all we have to do is inerit on-slave-by-default
|
107
118
|
# down from the parent now.
|
108
119
|
module Rails41HasAndBelongsToManyBuilderExtension
|
109
|
-
def
|
110
|
-
|
120
|
+
def self.included(base)
|
121
|
+
base.class_eval do
|
122
|
+
alias_method :through_model_without_inherit_default_slave_from_lhs, :through_model
|
123
|
+
alias_method :through_model, :through_model_with_inherit_default_slave_from_lhs
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def through_model_with_inherit_default_slave_from_lhs
|
128
|
+
model = through_model_without_inherit_default_slave_from_lhs
|
111
129
|
def model.on_slave_by_default?
|
112
130
|
left_reflection.klass.on_slave_by_default?
|
113
131
|
end
|
@@ -1,23 +1,19 @@
|
|
1
|
-
module ActiveRecordShards
|
2
|
-
module Migrator
|
3
|
-
[:up, :down, :run].each do |m|
|
4
|
-
define_method(m) do |*args|
|
5
|
-
ActiveRecord::Base.on_shard(nil) do
|
6
|
-
super(*args)
|
7
|
-
end
|
8
|
-
ActiveRecord::Base.on_all_shards do
|
9
|
-
super(*args)
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
ActiveRecord::Migrator.singleton_class.send(:prepend, ActiveRecordShards::Migrator)
|
17
|
-
|
18
1
|
module ActiveRecord
|
19
2
|
class Migrator
|
20
3
|
class << self
|
4
|
+
[:up, :down, :run].each do |m|
|
5
|
+
define_method("#{m}_with_sharding") do |*args|
|
6
|
+
ActiveRecord::Base.on_shard(nil) do
|
7
|
+
self.send("#{m}_without_sharding", *args)
|
8
|
+
end
|
9
|
+
ActiveRecord::Base.on_all_shards do
|
10
|
+
self.send("#{m}_without_sharding", *args)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
alias_method :"#{m}_without_sharding", m.to_sym
|
14
|
+
alias_method m.to_sym, :"#{m}_with_sharding"
|
15
|
+
end
|
16
|
+
|
21
17
|
def bootstrap_migrations_from_nil_shard(migrations_path, this_migration=nil)
|
22
18
|
migrations = nil
|
23
19
|
ActiveRecord::Base.on_shard(nil) do
|
@@ -88,7 +84,7 @@ module ActiveRecordShards
|
|
88
84
|
# migration, where it should have been. But this makes our monkey patch incompatible.
|
89
85
|
# So we're forced to *either* include or extend this.
|
90
86
|
module ActualMigrationExtension
|
91
|
-
def
|
87
|
+
def migrate_with_forced_shard(direction)
|
92
88
|
if migration_shard.blank?
|
93
89
|
raise RuntimeError, "#{self.name}: Can't run migrations without a shard spec: this may be :all, :none,
|
94
90
|
or a specific shard (for data-fixups). please call shard(arg) in your migration."
|
@@ -103,7 +99,7 @@ module ActiveRecordShards
|
|
103
99
|
return if migration_shard != :all && migration_shard.to_s != shard.to_s
|
104
100
|
end
|
105
101
|
|
106
|
-
|
102
|
+
migrate_without_forced_shard(direction)
|
107
103
|
end
|
108
104
|
end
|
109
105
|
end
|
@@ -111,10 +107,12 @@ end
|
|
111
107
|
ActiveRecord::Migration.class_eval do
|
112
108
|
extend ActiveRecordShards::MigrationClassExtension
|
113
109
|
|
114
|
-
|
110
|
+
include ActiveRecordShards::ActualMigrationExtension
|
115
111
|
define_method :migration_shard do
|
116
112
|
self.class.migration_shard
|
117
113
|
end
|
114
|
+
alias_method :migrate_without_forced_shard, :migrate
|
115
|
+
alias_method :migrate, :migrate_with_forced_shard
|
118
116
|
end
|
119
117
|
|
120
118
|
ActiveRecord::MigrationProxy.delegate :migration_shard, :to => :migration
|
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.6.
|
4
|
+
version: 3.6.1
|
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:
|
13
|
+
date: 2016-01-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|