activerecord-shard_for 0.1.0
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 +7 -0
- data/.gitignore +10 -0
- data/.rspec +2 -0
- data/.rubocop.yml +28 -0
- data/.travis.yml +4 -0
- data/Appraisals +26 -0
- data/CODE_OF_CONDUCT.md +49 -0
- data/Gemfile +5 -0
- data/Guardfile +21 -0
- data/LICENSE.txt +21 -0
- data/README.md +296 -0
- data/Rakefile +10 -0
- data/activerecord-shard_for.gemspec +40 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/gemfiles/.bundle/config +1 -0
- data/gemfiles/ar_4.1.0.gemfile +7 -0
- data/gemfiles/ar_4.1.0.gemfile.lock +186 -0
- data/gemfiles/ar_4.1.7.gemfile +7 -0
- data/gemfiles/ar_4.1.7.gemfile.lock +186 -0
- data/gemfiles/ar_4.1.8.gemfile +7 -0
- data/gemfiles/ar_4.1.8.gemfile.lock +186 -0
- data/gemfiles/ar_4.2.gemfile +7 -0
- data/gemfiles/ar_4.2.gemfile.lock +186 -0
- data/gemfiles/ar_5.0.gemfile +7 -0
- data/gemfiles/ar_5.0.gemfile.lock +182 -0
- data/gemfiles/rails_edge.gemfile +8 -0
- data/gemfiles/rails_edge.gemfile.lock +193 -0
- data/lib/activerecord/shard_for.rb +32 -0
- data/lib/activerecord/shard_for/all_shards_in_parallel.rb +43 -0
- data/lib/activerecord/shard_for/cluster_config.rb +32 -0
- data/lib/activerecord/shard_for/config.rb +45 -0
- data/lib/activerecord/shard_for/connection_router.rb +33 -0
- data/lib/activerecord/shard_for/database_tasks.rb +185 -0
- data/lib/activerecord/shard_for/errors.rb +14 -0
- data/lib/activerecord/shard_for/hash_modulo_router.rb +18 -0
- data/lib/activerecord/shard_for/model.rb +134 -0
- data/lib/activerecord/shard_for/railtie.rb +10 -0
- data/lib/activerecord/shard_for/replication_mapping.rb +37 -0
- data/lib/activerecord/shard_for/shard_repogitory.rb +69 -0
- data/lib/activerecord/shard_for/version.rb +5 -0
- data/lib/activerecord/tasks/activerecord_shard_for.rake +42 -0
- metadata +323 -0
@@ -0,0 +1,193 @@
|
|
1
|
+
GIT
|
2
|
+
remote: git://github.com/rails/arel.git
|
3
|
+
revision: 09827f361d4bc73e6ff157d9feb74a465e4e4cdd
|
4
|
+
specs:
|
5
|
+
arel (7.1.1)
|
6
|
+
|
7
|
+
GIT
|
8
|
+
remote: git://github.com/rails/rails.git
|
9
|
+
revision: 815b730b1b79158511f9f4c8465c476b9fe9b7e0
|
10
|
+
specs:
|
11
|
+
activemodel (5.1.0.alpha)
|
12
|
+
activesupport (= 5.1.0.alpha)
|
13
|
+
activerecord (5.1.0.alpha)
|
14
|
+
activemodel (= 5.1.0.alpha)
|
15
|
+
activesupport (= 5.1.0.alpha)
|
16
|
+
arel (~> 7.0)
|
17
|
+
activesupport (5.1.0.alpha)
|
18
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
19
|
+
i18n (~> 0.7)
|
20
|
+
minitest (~> 5.1)
|
21
|
+
tzinfo (~> 1.1)
|
22
|
+
|
23
|
+
PATH
|
24
|
+
remote: ../
|
25
|
+
specs:
|
26
|
+
activerecord-shard_for (0.1.0)
|
27
|
+
activerecord (>= 4.1.0)
|
28
|
+
activesupport (>= 4.1.0)
|
29
|
+
expeditor (>= 0.1.0)
|
30
|
+
|
31
|
+
GEM
|
32
|
+
remote: https://rubygems.org/
|
33
|
+
specs:
|
34
|
+
abstract_type (0.0.7)
|
35
|
+
adamantium (0.2.0)
|
36
|
+
ice_nine (~> 0.11.0)
|
37
|
+
memoizable (~> 0.4.0)
|
38
|
+
appraisal (2.1.0)
|
39
|
+
bundler
|
40
|
+
rake
|
41
|
+
thor (>= 0.14.0)
|
42
|
+
ast (2.3.0)
|
43
|
+
binding_of_caller (0.7.2)
|
44
|
+
debug_inspector (>= 0.0.1)
|
45
|
+
coderay (1.1.1)
|
46
|
+
concord (0.1.5)
|
47
|
+
adamantium (~> 0.2.0)
|
48
|
+
equalizer (~> 0.0.9)
|
49
|
+
concurrent-ruby (1.0.2)
|
50
|
+
concurrent-ruby-ext (1.0.2)
|
51
|
+
concurrent-ruby (~> 1.0.2)
|
52
|
+
debug_inspector (0.0.2)
|
53
|
+
diff-lcs (1.2.5)
|
54
|
+
equalizer (0.0.11)
|
55
|
+
expeditor (0.4.0)
|
56
|
+
concurrent-ruby (~> 1.0.0)
|
57
|
+
concurrent-ruby-ext (~> 1.0.0)
|
58
|
+
retryable (> 1.0)
|
59
|
+
ffi (1.9.14)
|
60
|
+
formatador (0.2.5)
|
61
|
+
guard (2.14.0)
|
62
|
+
formatador (>= 0.2.4)
|
63
|
+
listen (>= 2.7, < 4.0)
|
64
|
+
lumberjack (~> 1.0)
|
65
|
+
nenv (~> 0.1)
|
66
|
+
notiffany (~> 0.0)
|
67
|
+
pry (>= 0.9.12)
|
68
|
+
shellany (~> 0.0)
|
69
|
+
thor (>= 0.18.1)
|
70
|
+
guard-compat (1.2.1)
|
71
|
+
guard-rspec (4.7.3)
|
72
|
+
guard (~> 2.1)
|
73
|
+
guard-compat (~> 1.1)
|
74
|
+
rspec (>= 2.99.0, < 4.0)
|
75
|
+
guard-rubocop (1.2.0)
|
76
|
+
guard (~> 2.0)
|
77
|
+
rubocop (~> 0.20)
|
78
|
+
i18n (0.7.0)
|
79
|
+
ice_nine (0.11.2)
|
80
|
+
interception (0.5)
|
81
|
+
listen (3.1.5)
|
82
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
83
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
84
|
+
ruby_dep (~> 1.2)
|
85
|
+
lumberjack (1.0.10)
|
86
|
+
memoizable (0.4.2)
|
87
|
+
thread_safe (~> 0.3, >= 0.3.1)
|
88
|
+
method_source (0.8.2)
|
89
|
+
minitest (5.9.0)
|
90
|
+
nenv (0.3.0)
|
91
|
+
notiffany (0.1.1)
|
92
|
+
nenv (~> 0.1)
|
93
|
+
shellany (~> 0.0)
|
94
|
+
parser (2.3.1.2)
|
95
|
+
ast (~> 2.2)
|
96
|
+
powerpack (0.1.1)
|
97
|
+
proc_to_ast (0.1.0)
|
98
|
+
coderay
|
99
|
+
parser
|
100
|
+
unparser
|
101
|
+
procto (0.0.3)
|
102
|
+
pry (0.10.4)
|
103
|
+
coderay (~> 1.1.0)
|
104
|
+
method_source (~> 0.8.1)
|
105
|
+
slop (~> 3.4)
|
106
|
+
pry-doc (0.9.0)
|
107
|
+
pry (~> 0.9)
|
108
|
+
yard (~> 0.8)
|
109
|
+
pry-inline (1.0.2)
|
110
|
+
pry (~> 0.10.0)
|
111
|
+
unicode (~> 0.4.4)
|
112
|
+
pry-rescue (1.4.4)
|
113
|
+
interception (>= 0.5)
|
114
|
+
pry
|
115
|
+
pry-stack_explorer (0.4.9.2)
|
116
|
+
binding_of_caller (>= 0.7)
|
117
|
+
pry (>= 0.9.11)
|
118
|
+
rainbow (2.1.0)
|
119
|
+
rake (10.5.0)
|
120
|
+
rb-fsevent (0.9.7)
|
121
|
+
rb-inotify (0.9.7)
|
122
|
+
ffi (>= 0.5.0)
|
123
|
+
retryable (2.0.4)
|
124
|
+
rspec (3.5.0)
|
125
|
+
rspec-core (~> 3.5.0)
|
126
|
+
rspec-expectations (~> 3.5.0)
|
127
|
+
rspec-mocks (~> 3.5.0)
|
128
|
+
rspec-core (3.5.2)
|
129
|
+
rspec-support (~> 3.5.0)
|
130
|
+
rspec-expectations (3.5.0)
|
131
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
132
|
+
rspec-support (~> 3.5.0)
|
133
|
+
rspec-mocks (3.5.0)
|
134
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
135
|
+
rspec-support (~> 3.5.0)
|
136
|
+
rspec-parameterized (0.3.0)
|
137
|
+
binding_of_caller
|
138
|
+
parser
|
139
|
+
proc_to_ast
|
140
|
+
rspec (>= 2.13, < 4)
|
141
|
+
unparser
|
142
|
+
rspec-support (3.5.0)
|
143
|
+
rubocop (0.42.0)
|
144
|
+
parser (>= 2.3.1.1, < 3.0)
|
145
|
+
powerpack (~> 0.1)
|
146
|
+
rainbow (>= 1.99.1, < 3.0)
|
147
|
+
ruby-progressbar (~> 1.7)
|
148
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
149
|
+
ruby-progressbar (1.8.1)
|
150
|
+
ruby_dep (1.3.1)
|
151
|
+
shellany (0.0.1)
|
152
|
+
slop (3.6.0)
|
153
|
+
sqlite3 (1.3.11)
|
154
|
+
thor (0.19.1)
|
155
|
+
thread_safe (0.3.5)
|
156
|
+
tzinfo (1.2.2)
|
157
|
+
thread_safe (~> 0.1)
|
158
|
+
unicode (0.4.4.2)
|
159
|
+
unicode-display_width (1.1.0)
|
160
|
+
unparser (0.2.5)
|
161
|
+
abstract_type (~> 0.0.7)
|
162
|
+
adamantium (~> 0.2.0)
|
163
|
+
concord (~> 0.1.5)
|
164
|
+
diff-lcs (~> 1.2.5)
|
165
|
+
equalizer (~> 0.0.9)
|
166
|
+
parser (~> 2.3.0)
|
167
|
+
procto (~> 0.0.2)
|
168
|
+
yard (0.9.5)
|
169
|
+
|
170
|
+
PLATFORMS
|
171
|
+
ruby
|
172
|
+
|
173
|
+
DEPENDENCIES
|
174
|
+
activerecord!
|
175
|
+
activerecord-shard_for!
|
176
|
+
appraisal
|
177
|
+
arel!
|
178
|
+
bundler (~> 1.11)
|
179
|
+
guard-rspec
|
180
|
+
guard-rubocop
|
181
|
+
pry
|
182
|
+
pry-doc
|
183
|
+
pry-inline
|
184
|
+
pry-rescue
|
185
|
+
pry-stack_explorer
|
186
|
+
rake (~> 10.0)
|
187
|
+
rspec (~> 3.0)
|
188
|
+
rspec-parameterized
|
189
|
+
rubocop
|
190
|
+
sqlite3
|
191
|
+
|
192
|
+
BUNDLED WITH
|
193
|
+
1.12.5
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'expeditor'
|
3
|
+
require 'activerecord/shard_for/version'
|
4
|
+
require 'activerecord/shard_for/config'
|
5
|
+
require 'activerecord/shard_for/cluster_config'
|
6
|
+
require 'activerecord/shard_for/model'
|
7
|
+
require 'activerecord/shard_for/errors'
|
8
|
+
require 'activerecord/shard_for/cluster_router'
|
9
|
+
require 'activerecord/shard_for/hash_modulo_router'
|
10
|
+
require 'activerecord/shard_for/database_tasks'
|
11
|
+
require 'activerecord/shard_for/shard_repogitory'
|
12
|
+
require 'activerecord/shard_for/all_shards_in_parallel'
|
13
|
+
require 'activerecord/shard_for/replication_mapping'
|
14
|
+
require 'activerecord/railtie' if defined?(Rails5)
|
15
|
+
|
16
|
+
module ActiveRecord
|
17
|
+
module ShardFor
|
18
|
+
class << self
|
19
|
+
# @return [Activerecord::ShardFor::Config]
|
20
|
+
def config
|
21
|
+
@config ||= Config.new
|
22
|
+
end
|
23
|
+
|
24
|
+
# @yield [Activerecord::ShardFor::Config]
|
25
|
+
def configure(&block)
|
26
|
+
config.instance_eval(&block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
ActiveRecord::ShardFor.config.register_cluster_router(:hash_modulo, ActiveRecord::ShardFor::HashModuloRouter)
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
# Support parallel execution with each shard and deal with AR connection
|
3
|
+
# management in parallel execution.
|
4
|
+
module ShardFor
|
5
|
+
class AllShardsInParallel
|
6
|
+
# @param [Array<Class>] An array of shard model class
|
7
|
+
def initialize(shards)
|
8
|
+
@shards = shards
|
9
|
+
end
|
10
|
+
|
11
|
+
# @yield [Class] A shard model class
|
12
|
+
# @return [Array] A result
|
13
|
+
# @example
|
14
|
+
# User.all_shards_in_parallel.map(&:count).reduce(&:+)
|
15
|
+
def map
|
16
|
+
return [] unless block_given?
|
17
|
+
|
18
|
+
commands = @shards.map do |m|
|
19
|
+
Expeditor::Command.new { m.connection_pool.with_connection { yield m } }
|
20
|
+
end
|
21
|
+
commands.each(&:start)
|
22
|
+
commands.map(&:get)
|
23
|
+
end
|
24
|
+
|
25
|
+
# @yield [Class] A shard model class
|
26
|
+
# @return [Array] A result
|
27
|
+
# @example
|
28
|
+
# User.all_shards_in_parallel.flat_map {|m| m.where(age: 1) }
|
29
|
+
def flat_map(&block)
|
30
|
+
map(&block).flatten
|
31
|
+
end
|
32
|
+
|
33
|
+
# @yield [Class] A shard model class
|
34
|
+
# @return [ActiveRecord::ShardFor::AllShardsInParallel]
|
35
|
+
# @example
|
36
|
+
# User.all_shards_in_parallel.each {|m| puts m.count }
|
37
|
+
def each(&block)
|
38
|
+
map(&block) if block_given?
|
39
|
+
self
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ShardFor
|
3
|
+
class ClusterConfig
|
4
|
+
attr_reader :name, :connection_registry
|
5
|
+
|
6
|
+
# @param [Symbol] name
|
7
|
+
def initialize(name)
|
8
|
+
@name = name
|
9
|
+
@connection_registry = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
# @param [Object] key sharding key object for connection
|
13
|
+
# @param [Symbol] connection_name
|
14
|
+
# @raise [RuntimeError] when duplicate entry of key
|
15
|
+
def register(key, connection_name)
|
16
|
+
raise RuntimeError.new, "#{key} is registered" if connection_registry.key?(key)
|
17
|
+
connection_registry[key] = connection_name
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Array<Symbol>] An array of connection name
|
21
|
+
def connections
|
22
|
+
connection_registry.values
|
23
|
+
end
|
24
|
+
|
25
|
+
# @param [Object] key
|
26
|
+
# @return [Symbol] registered connection name
|
27
|
+
def fetch(key)
|
28
|
+
connection_registry.fetch(key)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ShardFor
|
3
|
+
class Config
|
4
|
+
attr_reader :cluster_configs, :routers
|
5
|
+
|
6
|
+
def initialize
|
7
|
+
@cluster_configs = {}
|
8
|
+
@routers = {}
|
9
|
+
end
|
10
|
+
|
11
|
+
# Define config for specific cluster.
|
12
|
+
# See README.md for example.
|
13
|
+
# @param [String] cluster_name
|
14
|
+
# @yield [ActiveRecord::ShardFor::ClusterConfig]
|
15
|
+
# @return [ActiveRecord::ShardFor::ClusterConfig]
|
16
|
+
# raise [RuntimeError] when this cluster config is invalid.
|
17
|
+
def define_cluster(cluster_name, &block)
|
18
|
+
cluster_config = ClusterConfig.new(cluster_name)
|
19
|
+
cluster_config.instance_eval(&block)
|
20
|
+
cluster_configs[cluster_name] = cluster_config
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param [Symbol] cluster_name
|
24
|
+
# @return [ActiveRecord::ShardFor::ClusterConfig]
|
25
|
+
# @raise [KeyError] when not registered key given
|
26
|
+
def fetch_cluster_config(cluster_name)
|
27
|
+
cluster_configs.fetch(cluster_name)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Register router for ActiveRecord::ShardFor
|
31
|
+
# See README.md for example.
|
32
|
+
# @param [Symbol] router_name
|
33
|
+
# @router_class [Class] router_class
|
34
|
+
def register_cluster_router(router_name, router_class)
|
35
|
+
routers[router_name] = router_class
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param [Symbol] router_name
|
39
|
+
# @return [Class] registered class by [#register_router]
|
40
|
+
def fetch_cluster_router(router_name)
|
41
|
+
routers[router_name]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ShardFor
|
3
|
+
# @abstract Subclass and override [#route] to inplement
|
4
|
+
class ConnectionRouter
|
5
|
+
attr_reader :cluster_config
|
6
|
+
|
7
|
+
# @param [ActiveRecord::ShardFor::ClusterConfig]
|
8
|
+
def initialize(cluster_config)
|
9
|
+
@cluster_config = cluster_config
|
10
|
+
end
|
11
|
+
|
12
|
+
# Fetch shard by sharding key
|
13
|
+
# @param [Object] key routing key
|
14
|
+
def fetch_connection_name(key)
|
15
|
+
cluster_config.fetch route(key)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Decide routing for shard.
|
19
|
+
# Override this method in subclass.
|
20
|
+
# @param [Object] key sharding key
|
21
|
+
def route(_key)
|
22
|
+
raise NotImplementedError.new, 'Please impement this method'
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
# @return [Integer] count of registered connection
|
28
|
+
def connection_count
|
29
|
+
cluster_config.connections.count
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
module ActiveRecord
|
2
|
+
module ShardFor
|
3
|
+
module DatabaseTasks
|
4
|
+
module_function
|
5
|
+
|
6
|
+
# @return [Boolean]
|
7
|
+
def ar5?
|
8
|
+
ActiveRecord::VERSION::MAJOR == 5
|
9
|
+
end
|
10
|
+
|
11
|
+
# @return [Boolean]
|
12
|
+
def ar4?
|
13
|
+
ActiveRecord::VERSION::MAJOR == 4
|
14
|
+
end
|
15
|
+
|
16
|
+
# @return [Boolean]
|
17
|
+
def ar42?
|
18
|
+
ar4? && ActiveRecord::VERSION::MINOR == 2
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [Boolean]
|
22
|
+
def ar41?
|
23
|
+
ar4? && ActiveRecord::VERSION::MINOR == 1
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [Boolean]
|
27
|
+
def ar417_above?
|
28
|
+
ar41? && ActiveRecord::VERSION::TINY > 7
|
29
|
+
end
|
30
|
+
|
31
|
+
# Show information of database sharding config.
|
32
|
+
def info
|
33
|
+
puts 'All clusters registered to ActiveRecord::ShardFor'
|
34
|
+
puts
|
35
|
+
clusters.each do |cluster|
|
36
|
+
puts "= Cluster: #{cluster.name} ="
|
37
|
+
cluster.connections.each do |name|
|
38
|
+
puts "- #{name}"
|
39
|
+
end
|
40
|
+
puts
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# @private
|
45
|
+
# @param [String] task_name
|
46
|
+
# @return [Rake::Task]
|
47
|
+
def to_rake_task(task_name)
|
48
|
+
Rake::Task[task_name]
|
49
|
+
end
|
50
|
+
|
51
|
+
# @private
|
52
|
+
# @return [Array<Symbol>]
|
53
|
+
def cluster_names
|
54
|
+
ActiveRecord::ShardFor.config.cluster_configs.keys
|
55
|
+
end
|
56
|
+
|
57
|
+
# @private
|
58
|
+
# @return [Array<ActiveRecord::ShardFor::ClusterConfig>]
|
59
|
+
def clusters
|
60
|
+
ActiveRecord::ShardFor.config.cluster_configs.values
|
61
|
+
end
|
62
|
+
|
63
|
+
# @private
|
64
|
+
# @return [ActiveRecord::ShardFor::ClusterConfig]
|
65
|
+
# @raise [KeyError]
|
66
|
+
def fetch_cluster_config(cluster_name)
|
67
|
+
ActiveRecord::ShardFor.config.fetch_cluster_config(cluster_name)
|
68
|
+
end
|
69
|
+
|
70
|
+
# For mock-ablity
|
71
|
+
# @private
|
72
|
+
def exit_with_error
|
73
|
+
exit 1
|
74
|
+
end
|
75
|
+
|
76
|
+
module TasksForMultipleClusters
|
77
|
+
# @param [String] task_name
|
78
|
+
def invoke_task_for_all_clusters(task_name)
|
79
|
+
cluster_names.each do |cluster_name|
|
80
|
+
invoke_task(task_name, cluster_name)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
# @private
|
85
|
+
# @param [String] name
|
86
|
+
# @param [Symbol] cluster_name
|
87
|
+
def invoke_task(name, cluster_name)
|
88
|
+
task_name = "activerecord:shard_for:#{name}"
|
89
|
+
to_rake_task(task_name).invoke(cluster_name.to_s)
|
90
|
+
to_rake_task(task_name).reenable
|
91
|
+
end
|
92
|
+
end
|
93
|
+
extend TasksForMultipleClusters
|
94
|
+
|
95
|
+
# Organize cluster config and handle error for invalid args, call single
|
96
|
+
# cluster task with each single connection config.
|
97
|
+
module TaskOrganizerForSingleClusterTask
|
98
|
+
# @param [Hash{Symbol => String}] args
|
99
|
+
def create_all_databases(args)
|
100
|
+
exec_task_for_all_databases('create', args)
|
101
|
+
end
|
102
|
+
|
103
|
+
# @param [Hash{Symbol => String}] args
|
104
|
+
def drop_all_databases(args)
|
105
|
+
exec_task_for_all_databases('drop', args)
|
106
|
+
end
|
107
|
+
|
108
|
+
# @param [Hash{Symbol => String}] args
|
109
|
+
def load_schema_all_databases(args)
|
110
|
+
exec_task_for_all_databases('load_schema', args)
|
111
|
+
end
|
112
|
+
|
113
|
+
private
|
114
|
+
|
115
|
+
# @param [String] task_name
|
116
|
+
# @param [Hash{Symbol => String}] args
|
117
|
+
def exec_task_for_all_databases(task_name, args)
|
118
|
+
cluster_name = cluster_name_or_error(task_name, args)
|
119
|
+
cluster = cluster_or_error(cluster_name)
|
120
|
+
cluster.connections.each do |connection_name|
|
121
|
+
__send__(task_name, connection_name.to_s)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
# @param [String] name A task name
|
126
|
+
# @param [Hash{Symbol => String}] args
|
127
|
+
# @return [String]
|
128
|
+
def cluster_name_or_error(name, args)
|
129
|
+
cluster_name = args[:cluster_name]
|
130
|
+
return cluster_name if cluster_name
|
131
|
+
|
132
|
+
$stderr.puts <<-MSG
|
133
|
+
Missing cluster_name. Find cluster_name via `rake activerecord:shard_for:info` then call `rake "activerecord:shard_for:#{name}[$cluster_name]"`.
|
134
|
+
MSG
|
135
|
+
exit_with_error
|
136
|
+
end
|
137
|
+
|
138
|
+
# @param [String] cluster_name
|
139
|
+
# @return [ActiveRecord::ShardFor::ClusterConfig]
|
140
|
+
def cluster_or_error(cluster_name)
|
141
|
+
fetch_cluster_config(cluster_name.to_sym)
|
142
|
+
rescue KeyError
|
143
|
+
$stderr.puts %(!cluster name "#{cluster_name}" not found.!)
|
144
|
+
exit_with_error
|
145
|
+
end
|
146
|
+
end
|
147
|
+
extend TaskOrganizerForSingleClusterTask
|
148
|
+
|
149
|
+
# Create, drop, load_schema for single connection config.
|
150
|
+
module TasksForSingleConnection
|
151
|
+
# @param [String] connection_name
|
152
|
+
def create(connection_name)
|
153
|
+
configuration = ActiveRecord::Base.configurations[connection_name]
|
154
|
+
ActiveRecord::Tasks::DatabaseTasks.create(configuration)
|
155
|
+
# Re-configure using configuration with database
|
156
|
+
ActiveRecord::Base.establish_connection(configuration)
|
157
|
+
end
|
158
|
+
|
159
|
+
# @param [String] connection_name
|
160
|
+
def drop(connection_name)
|
161
|
+
configuration = ActiveRecord::Base.configurations[connection_name]
|
162
|
+
ActiveRecord::Tasks::DatabaseTasks.drop(configuration)
|
163
|
+
end
|
164
|
+
|
165
|
+
# @param [String] connection_name
|
166
|
+
def load_schema(connection_name)
|
167
|
+
configuration = ActiveRecord::Base.configurations[connection_name]
|
168
|
+
|
169
|
+
case
|
170
|
+
when ar5?
|
171
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(configuration, :ruby)
|
172
|
+
when ar42? || ar417_above?
|
173
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema_for(configuration, :ruby)
|
174
|
+
when ar41?
|
175
|
+
ActiveRecord::Base.establish_connection(configuration)
|
176
|
+
ActiveRecord::Tasks::DatabaseTasks.load_schema(:ruby)
|
177
|
+
else
|
178
|
+
raise "This version of ActiveRecord is not supported: v#{ActiveRecord::VERSION::STRING}"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
extend TasksForSingleConnection
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|