active_record_shards 3.7.1 → 3.7.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/active_record_shards/association_collection_connection_selection.rb +1 -1
- data/lib/active_record_shards/configuration_parser.rb +5 -6
- data/lib/active_record_shards/connection_specification.rb +1 -1
- data/lib/active_record_shards/connection_switcher.rb +19 -20
- data/lib/active_record_shards/default_slave_patches.rb +17 -15
- data/lib/active_record_shards/migration.rb +3 -3
- data/lib/active_record_shards/model.rb +1 -1
- data/lib/active_record_shards/shard_selection.rb +1 -1
- data/lib/active_record_shards/shard_support.rb +1 -1
- data/lib/active_record_shards/tasks.rb +35 -36
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7cd066dedaafc888517b5363be4efc2d812cb85e
|
4
|
+
data.tar.gz: 1fe39d92a3875a9b4b2f36dd4bdfc1d94dee8047
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7c48a0f57a841dca2eb11960527fbb8f81d5e38e86ce4e2e0097ab43e8059776603e571a26264341ecd6b7201a31b8bf30470d090bb1c6c646bcedca1af9ddee
|
7
|
+
data.tar.gz: beab57cf1269253638b4a6653dcf3351748fac968e49f42dc67f0670c7f0c03b6cc28e5594809c55fc7ea724d41b4de552ee89dfb2dcd7ae18ed91bd106d811e
|
@@ -31,7 +31,7 @@ module ActiveRecordShards
|
|
31
31
|
@which = which
|
32
32
|
end
|
33
33
|
|
34
|
-
def method_missing(method, *args, &block)
|
34
|
+
def method_missing(method, *args, &block) # rubocop:disable Style/MethodMissing
|
35
35
|
# would love to not rely on version here, unfortunately @association_collection
|
36
36
|
# is a sensitive little bitch of an object.
|
37
37
|
reflection = @association_collection.proxy_association.reflection
|
@@ -9,12 +9,11 @@ module ActiveRecordShards
|
|
9
9
|
conf = conf.deep_dup
|
10
10
|
|
11
11
|
conf.to_a.each do |env_name, env_config|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
12
|
+
next unless shards = env_config.delete('shards')
|
13
|
+
env_config['shard_names'] = shards.keys
|
14
|
+
shards.each do |shard_name, shard_conf|
|
15
|
+
expand_child!(env_config, shard_conf)
|
16
|
+
conf["#{env_name}_shard_#{shard_name}"] = shard_conf
|
18
17
|
end
|
19
18
|
end
|
20
19
|
|
@@ -15,18 +15,18 @@ module ActiveRecordShards
|
|
15
15
|
|
16
16
|
def default_shard=(new_default_shard)
|
17
17
|
ActiveRecordShards::ShardSelection.default_shard = new_default_shard
|
18
|
-
switch_connection(:
|
18
|
+
switch_connection(shard: new_default_shard)
|
19
19
|
end
|
20
20
|
|
21
|
-
def on_shard(shard
|
21
|
+
def on_shard(shard)
|
22
22
|
old_options = current_shard_selection.options
|
23
|
-
switch_connection(:
|
23
|
+
switch_connection(shard: shard) if supports_sharding?
|
24
24
|
yield
|
25
25
|
ensure
|
26
26
|
switch_connection(old_options)
|
27
27
|
end
|
28
28
|
|
29
|
-
def on_first_shard
|
29
|
+
def on_first_shard
|
30
30
|
shard_name = shard_names.first
|
31
31
|
on_shard(shard_name) { yield }
|
32
32
|
end
|
@@ -35,11 +35,11 @@ module ActiveRecordShards
|
|
35
35
|
ShardSupport.new(self == ActiveRecord::Base ? nil : where(nil))
|
36
36
|
end
|
37
37
|
|
38
|
-
def on_all_shards
|
38
|
+
def on_all_shards
|
39
39
|
old_options = current_shard_selection.options
|
40
40
|
if supports_sharding?
|
41
41
|
shard_names.map do |shard|
|
42
|
-
switch_connection(:
|
42
|
+
switch_connection(shard: shard)
|
43
43
|
yield(shard)
|
44
44
|
end
|
45
45
|
else
|
@@ -96,11 +96,12 @@ module ActiveRecordShards
|
|
96
96
|
alias_method :with_slave_unless, :on_slave_unless
|
97
97
|
|
98
98
|
def on_cx_switch_block(which, options = {}, &block)
|
99
|
+
@disallow_slave ||= 0
|
99
100
|
old_options = current_shard_selection.options
|
100
|
-
switch_to_slave = (which == :slave &&
|
101
|
-
switch_connection(:
|
101
|
+
switch_to_slave = (which == :slave && @disallow_slave.zero?)
|
102
|
+
switch_connection(slave: switch_to_slave)
|
102
103
|
|
103
|
-
@disallow_slave
|
104
|
+
@disallow_slave += 1 if which == :master
|
104
105
|
|
105
106
|
# we avoid_readonly_scope to prevent some stack overflow problems, like when
|
106
107
|
# .columns calls .with_scope which calls .columns and onward, endlessly.
|
@@ -157,22 +158,20 @@ module ActiveRecordShards
|
|
157
158
|
ActiveRecordShards.rails_env
|
158
159
|
end
|
159
160
|
|
160
|
-
def
|
161
|
+
def with_default_shard
|
161
162
|
if is_sharded? && current_shard_id.nil? && table_name != ActiveRecord::Migrator.schema_migrations_table_name
|
162
|
-
on_first_shard {
|
163
|
+
on_first_shard { yield }
|
163
164
|
else
|
164
|
-
|
165
|
+
yield
|
165
166
|
end
|
166
167
|
end
|
167
168
|
|
168
|
-
def
|
169
|
-
|
170
|
-
|
171
|
-
if !result && is_sharded? && (shard_name = shard_names.first)
|
172
|
-
result = on_shard(shard_name) { table_exists_without_default_shard? }
|
173
|
-
end
|
169
|
+
def columns_with_default_shard
|
170
|
+
with_default_shard { columns_without_default_shard }
|
171
|
+
end
|
174
172
|
|
175
|
-
|
173
|
+
def table_exists_with_default_shard?
|
174
|
+
with_default_shard { table_exists_without_default_shard? }
|
176
175
|
end
|
177
176
|
|
178
177
|
class MasterSlaveProxy
|
@@ -181,7 +180,7 @@ module ActiveRecordShards
|
|
181
180
|
@which = which
|
182
181
|
end
|
183
182
|
|
184
|
-
def method_missing(method, *args, &block)
|
183
|
+
def method_missing(method, *args, &block) # rubocop:disable Style/MethodMissing
|
185
184
|
@target.on_master_or_slave(@which) { @target.send(method, *args, &block) }
|
186
185
|
end
|
187
186
|
end
|
@@ -2,11 +2,12 @@
|
|
2
2
|
module ActiveRecordShards
|
3
3
|
module DefaultSlavePatches
|
4
4
|
def self.wrap_method_in_on_slave(class_method, base, method)
|
5
|
-
base_methods =
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
5
|
+
base_methods =
|
6
|
+
if class_method
|
7
|
+
base.methods + base.private_methods
|
8
|
+
else
|
9
|
+
base.instance_methods + base.private_instance_methods
|
10
|
+
end
|
10
11
|
|
11
12
|
return unless base_methods.include?(method)
|
12
13
|
_, method, punctuation = method.to_s.match(/^(.*?)([\?\!]?)$/).to_a
|
@@ -25,13 +26,14 @@ module ActiveRecordShards
|
|
25
26
|
end
|
26
27
|
|
27
28
|
def columns_with_default_slave(*args, &block)
|
28
|
-
read_columns_from =
|
29
|
-
:
|
30
|
-
|
31
|
-
|
32
|
-
|
29
|
+
read_columns_from =
|
30
|
+
if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
|
31
|
+
:slave
|
32
|
+
else
|
33
|
+
:master
|
34
|
+
end
|
33
35
|
|
34
|
-
on_cx_switch_block(read_columns_from, :
|
36
|
+
on_cx_switch_block(read_columns_from, construct_ro_scope: false) { columns_without_default_slave(*args, &block) }
|
35
37
|
end
|
36
38
|
|
37
39
|
def transaction_with_slave_off(*args, &block)
|
@@ -58,7 +60,7 @@ module ActiveRecordShards
|
|
58
60
|
end
|
59
61
|
end
|
60
62
|
|
61
|
-
CLASS_SLAVE_METHODS = [:find_by_sql, :count_by_sql, :calculate, :find_one, :find_some, :find_every, :exists?, :table_exists?]
|
63
|
+
CLASS_SLAVE_METHODS = [:find_by_sql, :count_by_sql, :calculate, :find_one, :find_some, :find_every, :exists?, :table_exists?].freeze
|
62
64
|
|
63
65
|
def self.extended(base)
|
64
66
|
CLASS_SLAVE_METHODS.each { |m| ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(true, base, m) }
|
@@ -83,7 +85,7 @@ module ActiveRecordShards
|
|
83
85
|
end
|
84
86
|
end
|
85
87
|
|
86
|
-
def on_slave_unless_tx
|
88
|
+
def on_slave_unless_tx
|
87
89
|
if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
|
88
90
|
on_slave { yield }
|
89
91
|
else
|
@@ -112,7 +114,7 @@ module ActiveRecordShards
|
|
112
114
|
|
113
115
|
module HasAndBelongsToManyPreloaderPatches
|
114
116
|
def self.included(base)
|
115
|
-
ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, base, :records_for) rescue nil
|
117
|
+
ActiveRecordShards::DefaultSlavePatches.wrap_method_in_on_slave(false, base, :records_for) rescue nil # rubocop:disable Style/RescueModifier
|
116
118
|
end
|
117
119
|
|
118
120
|
def on_slave_unless_tx
|
@@ -142,7 +144,7 @@ module ActiveRecordShards
|
|
142
144
|
end
|
143
145
|
|
144
146
|
# also transfer the sharded-ness of the left table to the join model
|
145
|
-
model.not_sharded
|
147
|
+
model.not_sharded unless model.left_reflection.klass.is_sharded?
|
146
148
|
model
|
147
149
|
end
|
148
150
|
end
|
@@ -41,7 +41,7 @@ module ActiveRecord
|
|
41
41
|
|
42
42
|
# list of pending migrations is any migrations that haven't run on all shards.
|
43
43
|
def pending_migrations
|
44
|
-
pending,
|
44
|
+
pending, _missing = self.class.shard_status(migrations.map(&:version))
|
45
45
|
pending = pending.values.flatten
|
46
46
|
migrations.select { |m| pending.include?(m.version) }
|
47
47
|
end
|
@@ -66,7 +66,7 @@ module ActiveRecord
|
|
66
66
|
ActiveRecord::Base.on_shard(nil) { collect.call(nil) }
|
67
67
|
ActiveRecord::Base.on_all_shards { |shard| collect.call(shard) }
|
68
68
|
|
69
|
-
|
69
|
+
[pending, missing]
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -116,4 +116,4 @@ ActiveRecord::Migration.class_eval do
|
|
116
116
|
alias_method :migrate, :migrate_with_forced_shard
|
117
117
|
end
|
118
118
|
|
119
|
-
ActiveRecord::MigrationProxy.delegate :migration_shard, :
|
119
|
+
ActiveRecord::MigrationProxy.delegate :migration_shard, to: :migration
|
@@ -7,61 +7,60 @@ end
|
|
7
7
|
|
8
8
|
namespace :db do
|
9
9
|
desc 'Drops the database for the current RAILS_ENV including shards'
|
10
|
-
task :
|
10
|
+
task drop: :load_config do
|
11
11
|
ActiveRecord::Base.configurations.each do |key, conf|
|
12
|
-
if key.starts_with?(ActiveRecordShards.rails_env)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
end
|
12
|
+
next if !key.starts_with?(ActiveRecordShards.rails_env) || key.ends_with?("_slave")
|
13
|
+
begin
|
14
|
+
ActiveRecordShards::Tasks.root_connection(conf).drop_database(conf['database'])
|
15
|
+
# rescue ActiveRecord::NoDatabaseError # TODO: exists in AR but never is raised here ...
|
16
|
+
# $stderr.puts "Database '#{conf['database']}' does not exist"
|
17
|
+
rescue StandardError => error
|
18
|
+
$stderr.puts error, *error.backtrace
|
19
|
+
$stderr.puts "Couldn't drop #{conf['database']}"
|
21
20
|
end
|
22
21
|
end
|
23
22
|
end
|
24
23
|
|
25
|
-
task :
|
26
|
-
Rake.application.lookup('db:drop', t.scope).invoke rescue nil
|
24
|
+
task reset: :load_config do |t|
|
25
|
+
Rake.application.lookup('db:drop', t.scope).invoke rescue nil # rubocop:disable Style/RescueModifier
|
27
26
|
Rake.application.lookup('db:setup', t.scope).invoke
|
28
27
|
end
|
29
28
|
|
30
29
|
desc "Create the database defined in config/database.yml for the current RAILS_ENV including shards"
|
31
|
-
task :
|
30
|
+
task create: :load_config do
|
32
31
|
ActiveRecord::Base.configurations.each do |key, conf|
|
33
|
-
if key.starts_with?(ActiveRecordShards.rails_env)
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
32
|
+
next if !key.starts_with?(ActiveRecordShards.rails_env) || key.ends_with?("_slave")
|
33
|
+
if ActiveRecord::VERSION::MAJOR >= 4
|
34
|
+
begin
|
35
|
+
# MysqlAdapter takes charset instead of encoding in Rails 4
|
36
|
+
# https://github.com/rails/rails/commit/78b30fed9336336694fb2cb5d2825f95800b541c
|
37
|
+
symbolized_configuration = conf.symbolize_keys
|
38
|
+
symbolized_configuration[:charset] = symbolized_configuration[:encoding]
|
40
39
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
40
|
+
ActiveRecordShards::Tasks.root_connection(conf).create_database(conf['database'], symbolized_configuration)
|
41
|
+
rescue ActiveRecord::StatementInvalid => ex
|
42
|
+
if ex.message.include?('database exists')
|
43
|
+
puts "#{conf['database']} already exists"
|
44
|
+
else
|
45
|
+
raise ex
|
48
46
|
end
|
49
|
-
else
|
50
|
-
create_database(conf)
|
51
47
|
end
|
48
|
+
else
|
49
|
+
create_database(conf)
|
52
50
|
end
|
53
51
|
end
|
54
52
|
ActiveRecord::Base.establish_connection(ActiveRecordShards.rails_env.to_sym)
|
55
53
|
end
|
56
54
|
|
57
55
|
desc "Raises an error if there are pending migrations"
|
58
|
-
task :
|
56
|
+
task abort_if_pending_migrations: :environment do
|
59
57
|
if defined? ActiveRecord
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
58
|
+
pending_migrations =
|
59
|
+
if Rails::VERSION::MAJOR >= 4
|
60
|
+
ActiveRecord::Base.on_shard(nil) { ActiveRecord::Migrator.open(ActiveRecord::Migrator.migrations_paths).pending_migrations }
|
61
|
+
else
|
62
|
+
ActiveRecord::Base.on_shard(nil) { ActiveRecord::Migrator.new(:up, 'db/migrate').pending_migrations }
|
63
|
+
end
|
65
64
|
|
66
65
|
if pending_migrations.any?
|
67
66
|
puts "You have #{pending_migrations.size} pending migrations:"
|
@@ -75,7 +74,7 @@ namespace :db do
|
|
75
74
|
|
76
75
|
namespace :test do
|
77
76
|
desc 'Purges the test databases by dropping and creating'
|
78
|
-
task :
|
77
|
+
task purge: :load_config do |t|
|
79
78
|
begin
|
80
79
|
saved_env = Rails.env
|
81
80
|
Rails.env = 'test'
|
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.7.
|
4
|
+
version: 3.7.2
|
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-09-22 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -228,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
228
228
|
version: '0'
|
229
229
|
requirements: []
|
230
230
|
rubyforge_project:
|
231
|
-
rubygems_version: 2.5.1
|
231
|
+
rubygems_version: 2.4.5.1
|
232
232
|
signing_key:
|
233
233
|
specification_version: 4
|
234
234
|
summary: Simple database switching for ActiveRecord.
|