active_record_shards 3.22.0 → 4.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +57 -126
- data/lib/active_record_shards/association_collection_connection_selection.rb +14 -23
- data/lib/active_record_shards/configuration_parser.rb +6 -30
- data/lib/active_record_shards/connection_switcher-5-0.rb +0 -10
- data/lib/active_record_shards/connection_switcher-5-1.rb +0 -10
- data/lib/active_record_shards/connection_switcher.rb +71 -115
- data/lib/active_record_shards/default_slave_patches.rb +134 -3
- data/lib/active_record_shards/model.rb +16 -35
- data/lib/active_record_shards/shard_selection.rb +27 -66
- data/lib/active_record_shards/shard_support.rb +0 -1
- data/lib/active_record_shards/sharded_model.rb +15 -0
- data/lib/active_record_shards/sql_comments.rb +4 -11
- data/lib/active_record_shards/tasks.rb +22 -41
- data/lib/active_record_shards.rb +6 -126
- metadata +64 -74
- data/lib/active_record_shards/connection_handler.rb +0 -8
- data/lib/active_record_shards/connection_pool.rb +0 -36
- data/lib/active_record_shards/connection_specification.rb +0 -19
- data/lib/active_record_shards/connection_switcher-4-2.rb +0 -56
- data/lib/active_record_shards/connection_switcher-6-0.rb +0 -30
- data/lib/active_record_shards/default_replica_patches.rb +0 -278
- data/lib/active_record_shards/deprecation.rb +0 -12
- data/lib/active_record_shards/migration.rb +0 -125
- data/lib/active_record_shards/patches-4-2.rb +0 -9
- data/lib/active_record_shards/schema_dumper_extension.rb +0 -42
@@ -1,56 +0,0 @@
|
|
1
|
-
module ActiveRecordShards
|
2
|
-
module ConnectionSwitcher
|
3
|
-
# Name of the connection pool. Used by ConnectionHandler to retrieve the current connection pool.
|
4
|
-
def connection_pool_name # :nodoc:
|
5
|
-
name = current_shard_selection.shard_name(self)
|
6
|
-
|
7
|
-
# e.g. if "production_replica" is not defined in `Configuration`, fall back to "production"
|
8
|
-
if configurations[name].nil? && on_replica?
|
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
|
-
if spec.nil?
|
26
|
-
raise ActiveRecord::AdapterNotSpecified, "No database defined by #{name} in your database config. (configurations: #{configurations.keys.inspect})"
|
27
|
-
end
|
28
|
-
|
29
|
-
specification_cache[name] ||= begin
|
30
|
-
resolver = ActiveRecordShards::ConnectionSpecification::Resolver.new configurations
|
31
|
-
resolver.spec(spec)
|
32
|
-
end
|
33
|
-
|
34
|
-
connection_handler.establish_connection(self, specification_cache[name])
|
35
|
-
end
|
36
|
-
|
37
|
-
def specification_cache
|
38
|
-
@@specification_cache ||= {}
|
39
|
-
end
|
40
|
-
|
41
|
-
# Helper method to clear global state when testing.
|
42
|
-
def clear_specification_cache
|
43
|
-
@@specification_cache = {}
|
44
|
-
end
|
45
|
-
|
46
|
-
def connection_pool_key
|
47
|
-
specification_cache[connection_pool_name]
|
48
|
-
end
|
49
|
-
|
50
|
-
def connected_to_shard?
|
51
|
-
specs_to_pools = Hash[connection_handler.connection_pool_list.map { |pool| [pool.spec, pool] }]
|
52
|
-
|
53
|
-
specs_to_pools.key?(connection_pool_key)
|
54
|
-
end
|
55
|
-
end
|
56
|
-
end
|
@@ -1,30 +0,0 @@
|
|
1
|
-
module ActiveRecordShards
|
2
|
-
module ConnectionSwitcher
|
3
|
-
def connection_specification_name
|
4
|
-
name = current_shard_selection.resolve_connection_name(sharded: is_sharded?, configurations: configurations)
|
5
|
-
|
6
|
-
@_ars_connection_specification_names ||= {}
|
7
|
-
unless @_ars_connection_specification_names.include?(name)
|
8
|
-
unless configurations[name] || name == "primary"
|
9
|
-
raise ActiveRecord::AdapterNotSpecified, "No database defined by #{name} in your database config. (configurations: #{configurations.to_h.keys.inspect})"
|
10
|
-
end
|
11
|
-
|
12
|
-
@_ars_connection_specification_names[name] = true
|
13
|
-
end
|
14
|
-
|
15
|
-
name
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def ensure_shard_connection
|
21
|
-
# See if we've connected before. If not, call `#establish_connection`
|
22
|
-
# so that ActiveRecord can resolve connection_specification_name to an
|
23
|
-
# ARS connection.
|
24
|
-
spec_name = connection_specification_name
|
25
|
-
|
26
|
-
pool = connection_handler.retrieve_connection_pool(spec_name)
|
27
|
-
connection_handler.establish_connection(spec_name.to_sym) if pool.nil?
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
@@ -1,278 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveRecordShards
|
4
|
-
module DefaultReplicaPatches
|
5
|
-
def self.wrap_method_in_on_replica(class_method, base, method, force_on_replica: false)
|
6
|
-
base_methods =
|
7
|
-
if class_method
|
8
|
-
base.methods + base.private_methods
|
9
|
-
else
|
10
|
-
base.instance_methods + base.private_instance_methods
|
11
|
-
end
|
12
|
-
|
13
|
-
return unless base_methods.include?(method)
|
14
|
-
|
15
|
-
_, method, punctuation = method.to_s.match(/^(.*?)([\?\!]?)$/).to_a
|
16
|
-
# _ALWAYS_ on replica, or only for on `on_replica_by_default = true` models?
|
17
|
-
wrapper = force_on_replica ? 'force_on_replica' : 'on_replica_unless_tx'
|
18
|
-
base.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
19
|
-
#{class_method ? 'class << self' : ''}
|
20
|
-
def #{method}_with_default_replica#{punctuation}(*args, &block)
|
21
|
-
#{wrapper} do
|
22
|
-
#{method}_without_default_replica#{punctuation}(*args, &block)
|
23
|
-
end
|
24
|
-
end
|
25
|
-
|
26
|
-
alias_method :#{method}_without_default_replica#{punctuation}, :#{method}#{punctuation}
|
27
|
-
alias_method :#{method}#{punctuation}, :#{method}_with_default_replica#{punctuation}
|
28
|
-
#{class_method ? 'end' : ''}
|
29
|
-
RUBY
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.wrap_method_in_on_slave(*args)
|
33
|
-
ActiveRecordShards::Deprecation.deprecation_warning(
|
34
|
-
:'self.wrap_method_in_on_slave',
|
35
|
-
:'self.wrap_method_in_on_replica'
|
36
|
-
)
|
37
|
-
wrap_method_in_on_replica(*args)
|
38
|
-
end
|
39
|
-
|
40
|
-
def transaction_with_replica_off(*args, &block)
|
41
|
-
if on_replica_by_default?
|
42
|
-
begin
|
43
|
-
old_val = Thread.current[:_active_record_shards_in_tx]
|
44
|
-
Thread.current[:_active_record_shards_in_tx] = true
|
45
|
-
transaction_without_replica_off(*args, &block)
|
46
|
-
ensure
|
47
|
-
Thread.current[:_active_record_shards_in_tx] = old_val
|
48
|
-
end
|
49
|
-
else
|
50
|
-
transaction_without_replica_off(*args, &block)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
alias_method :transaction_with_slave_off, :transaction_with_replica_off
|
54
|
-
|
55
|
-
module InstanceMethods
|
56
|
-
# fix ActiveRecord to do the right thing, and use our aliased quote_value
|
57
|
-
def quote_value(*args, &block)
|
58
|
-
self.class.quote_value(*args, &block)
|
59
|
-
end
|
60
|
-
|
61
|
-
def on_replica_unless_tx
|
62
|
-
self.class.on_replica_unless_tx { yield }
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
CLASS_REPLICA_METHODS = [
|
67
|
-
:calculate,
|
68
|
-
:count_by_sql,
|
69
|
-
:exists?,
|
70
|
-
:find,
|
71
|
-
:find_by,
|
72
|
-
:find_by_sql,
|
73
|
-
:find_every,
|
74
|
-
:find_one,
|
75
|
-
:find_some,
|
76
|
-
:get_primary_key
|
77
|
-
].freeze
|
78
|
-
|
79
|
-
CLASS_FORCE_REPLICA_METHODS = [
|
80
|
-
:replace_bind_variable,
|
81
|
-
:replace_bind_variables,
|
82
|
-
:sanitize_sql_array,
|
83
|
-
:sanitize_sql_hash_for_assignment,
|
84
|
-
:table_exists?
|
85
|
-
].freeze
|
86
|
-
|
87
|
-
CLASS_SLAVE_METHODS = CLASS_REPLICA_METHODS
|
88
|
-
CLASS_FORCE_SLAVE_METHODS = CLASS_FORCE_REPLICA_METHODS
|
89
|
-
|
90
|
-
def self.extended(base)
|
91
|
-
CLASS_REPLICA_METHODS.each { |m| ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(true, base, m) }
|
92
|
-
CLASS_FORCE_REPLICA_METHODS.each { |m| ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(true, base, m, force_on_replica: true) }
|
93
|
-
|
94
|
-
if ActiveRecord::VERSION::MAJOR >= 5
|
95
|
-
ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(true, base, :load_schema!, force_on_replica: true)
|
96
|
-
else
|
97
|
-
ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(true, base, :columns, force_on_replica: true)
|
98
|
-
end
|
99
|
-
|
100
|
-
ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(false, base, :reload)
|
101
|
-
|
102
|
-
base.class_eval do
|
103
|
-
include InstanceMethods
|
104
|
-
|
105
|
-
class << self
|
106
|
-
alias_method :transaction_without_replica_off, :transaction
|
107
|
-
alias_method :transaction, :transaction_with_replica_off
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
def on_replica_unless_tx(&block)
|
113
|
-
return yield if Thread.current[:_active_record_shards_in_migration]
|
114
|
-
return yield if Thread.current[:_active_record_shards_in_tx]
|
115
|
-
|
116
|
-
if on_replica_by_default?
|
117
|
-
on_replica(&block)
|
118
|
-
else
|
119
|
-
yield
|
120
|
-
end
|
121
|
-
end
|
122
|
-
alias_method :on_slave_unless_tx, :on_replica_unless_tx
|
123
|
-
|
124
|
-
def force_on_replica(&block)
|
125
|
-
return yield if Thread.current[:_active_record_shards_in_migration]
|
126
|
-
|
127
|
-
on_cx_switch_block(:replica, construct_ro_scope: false, force: true, &block)
|
128
|
-
end
|
129
|
-
|
130
|
-
module ActiveRelationPatches
|
131
|
-
def self.included(base)
|
132
|
-
[:calculate, :exists?, :pluck, :load].each do |m|
|
133
|
-
ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(false, base, m)
|
134
|
-
end
|
135
|
-
|
136
|
-
if ActiveRecord::VERSION::MAJOR == 4
|
137
|
-
# `where` and `having` clauses call `create_binds`, which will use the primary connection
|
138
|
-
ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(false, base, :create_binds, force_on_replica: true)
|
139
|
-
end
|
140
|
-
|
141
|
-
ActiveRecordShards::DefaultReplicaPatches.wrap_method_in_on_replica(false, base, :to_sql, force_on_replica: true)
|
142
|
-
end
|
143
|
-
|
144
|
-
def on_replica_unless_tx
|
145
|
-
@klass.on_replica_unless_tx { yield }
|
146
|
-
end
|
147
|
-
end
|
148
|
-
|
149
|
-
module Rails52RelationPatches
|
150
|
-
def connection
|
151
|
-
return super if Thread.current[:_active_record_shards_in_migration]
|
152
|
-
return super if Thread.current[:_active_record_shards_in_tx]
|
153
|
-
|
154
|
-
if @klass.on_replica_by_default?
|
155
|
-
@klass.on_replica.connection
|
156
|
-
else
|
157
|
-
super
|
158
|
-
end
|
159
|
-
end
|
160
|
-
end
|
161
|
-
|
162
|
-
# in rails 4.1+, they create a join class that's used to pull in records for HABTM.
|
163
|
-
# this simplifies the hell out of our existence, because all we have to do is inerit on-replica-by-default
|
164
|
-
# down from the parent now.
|
165
|
-
module Rails41HasAndBelongsToManyBuilderExtension
|
166
|
-
def self.included(base)
|
167
|
-
base.class_eval do
|
168
|
-
alias_method :through_model_without_inherit_default_replica_from_lhs, :through_model
|
169
|
-
alias_method :through_model, :through_model_with_inherit_default_replica_from_lhs
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
|
-
def through_model_with_inherit_default_replica_from_lhs
|
174
|
-
model = through_model_without_inherit_default_replica_from_lhs
|
175
|
-
def model.on_replica_by_default?
|
176
|
-
left_reflection.klass.on_replica_by_default?
|
177
|
-
end
|
178
|
-
|
179
|
-
# also transfer the sharded-ness of the left table to the join model
|
180
|
-
model.not_sharded unless model.left_reflection.klass.is_sharded?
|
181
|
-
model
|
182
|
-
end
|
183
|
-
end
|
184
|
-
|
185
|
-
module AssociationsAssociationAssociationScopePatch
|
186
|
-
def association_scope
|
187
|
-
if klass
|
188
|
-
on_replica_unless_tx { super }
|
189
|
-
else
|
190
|
-
super
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
def on_replica_unless_tx
|
195
|
-
klass.on_replica_unless_tx { yield }
|
196
|
-
end
|
197
|
-
end
|
198
|
-
|
199
|
-
module AssociationsAssociationFindTargetPatch
|
200
|
-
def find_target
|
201
|
-
if klass
|
202
|
-
on_replica_unless_tx { super }
|
203
|
-
else
|
204
|
-
super
|
205
|
-
end
|
206
|
-
end
|
207
|
-
|
208
|
-
def on_replica_unless_tx
|
209
|
-
klass.on_replica_unless_tx { yield }
|
210
|
-
end
|
211
|
-
end
|
212
|
-
|
213
|
-
module AssociationsAssociationGetRecordsPatch
|
214
|
-
def get_records # rubocop:disable Naming/AccessorMethodName
|
215
|
-
if klass
|
216
|
-
on_replica_unless_tx { super }
|
217
|
-
else
|
218
|
-
super
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
def on_replica_unless_tx
|
223
|
-
klass.on_replica_unless_tx { yield }
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
module AssociationsPreloaderAssociationAssociatedRecordsByOwnerPatch
|
228
|
-
def associated_records_by_owner(preloader)
|
229
|
-
if klass
|
230
|
-
on_replica_unless_tx { super }
|
231
|
-
else
|
232
|
-
super
|
233
|
-
end
|
234
|
-
end
|
235
|
-
|
236
|
-
def on_replica_unless_tx
|
237
|
-
klass.on_replica_unless_tx { yield }
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
module AssociationsPreloaderAssociationLoadRecordsPatch
|
242
|
-
def load_records
|
243
|
-
if klass
|
244
|
-
on_replica_unless_tx { super }
|
245
|
-
else
|
246
|
-
super
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
def on_replica_unless_tx
|
251
|
-
klass.on_replica_unless_tx { yield }
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
module TypeCasterConnectionConnectionPatch
|
256
|
-
def connection
|
257
|
-
return super if Thread.current[:_active_record_shards_in_migration]
|
258
|
-
return super if Thread.current[:_active_record_shards_in_tx]
|
259
|
-
|
260
|
-
if @klass.on_replica_by_default?
|
261
|
-
@klass.on_replica.connection
|
262
|
-
else
|
263
|
-
super
|
264
|
-
end
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
module SchemaDefinePatch
|
269
|
-
def define(info, &block)
|
270
|
-
old_val = Thread.current[:_active_record_shards_in_migration]
|
271
|
-
Thread.current[:_active_record_shards_in_migration] = true
|
272
|
-
super
|
273
|
-
ensure
|
274
|
-
Thread.current[:_active_record_shards_in_migration] = old_val
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|
278
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
module ActiveRecordShards
|
2
|
-
class Deprecation < ActiveSupport::Deprecation
|
3
|
-
# This allows us to define separate deprecation behavior for ActiveRecordShards, but defaults to
|
4
|
-
# the same behavior globally configured with ActiveSupport.
|
5
|
-
#
|
6
|
-
# For example, this allows us to silence our own deprecation warnings in test while still being
|
7
|
-
# able to fail tests for upstream deprecation warnings.
|
8
|
-
def behavior
|
9
|
-
@behavior ||= ActiveSupport::Deprecation.behavior
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,125 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveRecord
|
4
|
-
class Migrator
|
5
|
-
def self.shards_migration_context
|
6
|
-
if ActiveRecord::VERSION::MAJOR >= 6
|
7
|
-
ActiveRecord::MigrationContext.new(ActiveRecord::Migrator.migrations_paths, ActiveRecord::SchemaMigration)
|
8
|
-
elsif ActiveRecord::VERSION::STRING >= '5.2.0'
|
9
|
-
ActiveRecord::MigrationContext.new(ActiveRecord::Migrator.migrations_paths)
|
10
|
-
else
|
11
|
-
self
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def initialize_with_sharding(*args)
|
16
|
-
initialize_without_sharding(*args)
|
17
|
-
|
18
|
-
# Rails creates the internal tables on the unsharded DB. We make them
|
19
|
-
# manually on the sharded DBs.
|
20
|
-
ActiveRecord::Base.on_all_shards do
|
21
|
-
ActiveRecord::SchemaMigration.create_table
|
22
|
-
if ActiveRecord::VERSION::MAJOR >= 5
|
23
|
-
ActiveRecord::InternalMetadata.create_table
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
alias_method :initialize_without_sharding, :initialize
|
28
|
-
alias_method :initialize, :initialize_with_sharding
|
29
|
-
|
30
|
-
def run_with_sharding
|
31
|
-
ActiveRecord::Base.on_shard(nil) { run_without_sharding }
|
32
|
-
ActiveRecord::Base.on_all_shards { run_without_sharding }
|
33
|
-
end
|
34
|
-
alias_method :run_without_sharding, :run
|
35
|
-
alias_method :run, :run_with_sharding
|
36
|
-
|
37
|
-
def migrate_with_sharding
|
38
|
-
ActiveRecord::Base.on_shard(nil) { migrate_without_sharding }
|
39
|
-
ActiveRecord::Base.on_all_shards { migrate_without_sharding }
|
40
|
-
end
|
41
|
-
alias_method :migrate_without_sharding, :migrate
|
42
|
-
alias_method :migrate, :migrate_with_sharding
|
43
|
-
|
44
|
-
# don't allow Migrator class to cache versions
|
45
|
-
undef migrated
|
46
|
-
def migrated
|
47
|
-
self.class.shards_migration_context.get_all_versions
|
48
|
-
end
|
49
|
-
|
50
|
-
# list of pending migrations is any migrations that haven't run on all shards.
|
51
|
-
undef pending_migrations
|
52
|
-
def pending_migrations
|
53
|
-
pending, _missing = self.class.shard_status(migrations.map(&:version))
|
54
|
-
pending = pending.values.flatten
|
55
|
-
migrations.select { |m| pending.include?(m.version) }
|
56
|
-
end
|
57
|
-
|
58
|
-
# public
|
59
|
-
# list of pending and missing versions per shard
|
60
|
-
# [{1 => [1234567]}, {1 => [2345678]}]
|
61
|
-
def self.shard_status(versions)
|
62
|
-
pending = {}
|
63
|
-
missing = {}
|
64
|
-
|
65
|
-
collect = lambda do |shard|
|
66
|
-
migrated = shards_migration_context.get_all_versions
|
67
|
-
|
68
|
-
p = versions - migrated
|
69
|
-
pending[shard] = p if p.any?
|
70
|
-
|
71
|
-
m = migrated - versions
|
72
|
-
missing[shard] = m if m.any?
|
73
|
-
end
|
74
|
-
|
75
|
-
ActiveRecord::Base.on_shard(nil) { collect.call(nil) }
|
76
|
-
ActiveRecord::Base.on_all_shards { |shard| collect.call(shard) }
|
77
|
-
|
78
|
-
[pending, missing]
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
module ActiveRecordShards
|
84
|
-
module MigrationClassExtension
|
85
|
-
attr_accessor :migration_shard
|
86
|
-
|
87
|
-
def shard(arg = nil)
|
88
|
-
self.migration_shard = arg
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
module ActualMigrationExtension
|
93
|
-
def migrate_with_forced_shard(direction)
|
94
|
-
if migration_shard.blank?
|
95
|
-
raise "#{name}: Can't run migrations without a shard spec: this may be :all, :none,
|
96
|
-
or a specific shard (for data-fixups). please call shard(arg) in your migration."
|
97
|
-
end
|
98
|
-
|
99
|
-
shard = ActiveRecord::Base.current_shard_selection.shard
|
100
|
-
|
101
|
-
if shard.nil?
|
102
|
-
return if migration_shard != :none
|
103
|
-
else
|
104
|
-
return if migration_shard == :none
|
105
|
-
return if migration_shard != :all && migration_shard.to_s != shard.to_s
|
106
|
-
end
|
107
|
-
|
108
|
-
migrate_without_forced_shard(direction)
|
109
|
-
end
|
110
|
-
|
111
|
-
def migration_shard
|
112
|
-
self.class.migration_shard
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
ActiveRecord::Migration.class_eval do
|
118
|
-
extend ActiveRecordShards::MigrationClassExtension
|
119
|
-
include ActiveRecordShards::ActualMigrationExtension
|
120
|
-
|
121
|
-
alias_method :migrate_without_forced_shard, :migrate
|
122
|
-
alias_method :migrate, :migrate_with_forced_shard
|
123
|
-
end
|
124
|
-
|
125
|
-
ActiveRecord::MigrationProxy.delegate :migration_shard, to: :migration
|
@@ -1,9 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'active_record_shards/connection_pool'
|
4
|
-
require 'active_record_shards/connection_handler'
|
5
|
-
require 'active_record_shards/connection_specification'
|
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)
|
@@ -1,42 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module ActiveRecordShards
|
4
|
-
module SchemaDumperExtension
|
5
|
-
def dump(stream)
|
6
|
-
stream = super(stream)
|
7
|
-
original_connection = @connection
|
8
|
-
|
9
|
-
if ActiveRecord::Base.supports_sharding?
|
10
|
-
ActiveRecord::Base.on_first_shard do
|
11
|
-
@connection = ActiveRecord::Base.connection
|
12
|
-
shard_header(stream)
|
13
|
-
extensions(stream)
|
14
|
-
tables(stream)
|
15
|
-
shard_trailer(stream)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
stream
|
20
|
-
ensure
|
21
|
-
@connection = original_connection
|
22
|
-
end
|
23
|
-
|
24
|
-
def shard_header(stream)
|
25
|
-
define_params = @version ? "version: #{@version}" : ""
|
26
|
-
|
27
|
-
stream.puts <<~HEADER
|
28
|
-
|
29
|
-
|
30
|
-
# This section generated by active_record_shards
|
31
|
-
|
32
|
-
ActiveRecord::Base.on_all_shards do
|
33
|
-
ActiveRecord::Schema.define(#{define_params}) do
|
34
|
-
|
35
|
-
HEADER
|
36
|
-
end
|
37
|
-
|
38
|
-
def shard_trailer(stream)
|
39
|
-
stream.puts "end\nend"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
end
|