active_record_shards 3.7.1 → 3.7.2
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/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.
|