activerecord-turntable 3.0.0.alpha3 → 3.0.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 +4 -4
- data/.gitmodules +3 -0
- data/.rubocop.yml +18 -0
- data/.rubocop_todo.yml +153 -0
- data/.travis.yml +20 -4
- data/CHANGELOG.md +32 -0
- data/Guardfile +2 -2
- data/README.md +68 -14
- data/Rakefile +42 -0
- data/activerecord-turntable.gemspec +13 -3
- data/gemfiles/rails_edge.gemfile +8 -0
- data/lib/active_record/turntable/active_record_ext/abstract_adapter.rb +3 -1
- data/lib/active_record/turntable/active_record_ext/activerecord_import_ext.rb +5 -7
- data/lib/active_record/turntable/active_record_ext/acts_as_archive_extension.rb +2 -2
- data/lib/active_record/turntable/active_record_ext/association.rb +3 -3
- data/lib/active_record/turntable/active_record_ext/clever_load.rb +2 -2
- data/lib/active_record/turntable/active_record_ext/database_tasks.rb +10 -8
- data/lib/active_record/turntable/active_record_ext/fixtures.rb +15 -13
- data/lib/active_record/turntable/active_record_ext/log_subscriber.rb +6 -0
- data/lib/active_record/turntable/active_record_ext/persistence.rb +25 -23
- data/lib/active_record/turntable/active_record_ext/schema_dumper.rb +8 -75
- data/lib/active_record/turntable/algorithm/range_algorithm.rb +6 -7
- data/lib/active_record/turntable/algorithm/range_bsearch_algorithm.rb +6 -7
- data/lib/active_record/turntable/base.rb +2 -17
- data/lib/active_record/turntable/cluster_helper_methods.rb +7 -4
- data/lib/active_record/turntable/connection_proxy.rb +4 -2
- data/lib/active_record/turntable/migration.rb +3 -5
- data/lib/active_record/turntable/mixer.rb +20 -19
- data/lib/active_record/turntable/pool_proxy.rb +20 -14
- data/lib/active_record/turntable/query_cache.rb +1 -1
- data/lib/active_record/turntable/railties/databases.rake +12 -12
- data/lib/active_record/turntable/seq_shard.rb +1 -1
- data/lib/active_record/turntable/sequencer/barrage.rb +3 -2
- data/lib/active_record/turntable/sequencer.rb +33 -29
- data/lib/active_record/turntable/shard.rb +8 -8
- data/lib/active_record/turntable/sharding_condition.rb +14 -14
- data/lib/active_record/turntable/sql_tree_patch.rb +7 -3
- data/lib/active_record/turntable/util.rb +4 -2
- data/lib/active_record/turntable/version.rb +1 -1
- data/lib/active_record/turntable.rb +6 -5
- data/lib/activerecord-turntable.rb +1 -0
- metadata +120 -101
- data/lib/active_record/turntable/helpers/test_helper.rb +0 -25
- data/lib/active_record/turntable/helpers.rb +0 -9
- data/spec/active_record/turntable/active_record_ext/association_preloader_spec.rb +0 -78
- data/spec/active_record/turntable/active_record_ext/association_spec.rb +0 -81
- data/spec/active_record/turntable/active_record_ext/clever_load_spec.rb +0 -72
- data/spec/active_record/turntable/active_record_ext/fixture_set_spec.rb +0 -27
- data/spec/active_record/turntable/active_record_ext/locking_optimistic_spec.rb +0 -28
- data/spec/active_record/turntable/active_record_ext/migration_spec.rb +0 -38
- data/spec/active_record/turntable/active_record_ext/persistence_spec.rb +0 -211
- data/spec/active_record/turntable/active_record_ext/sequencer_spec.rb +0 -22
- data/spec/active_record/turntable/active_record_ext/test_fixtures_spec.rb +0 -34
- data/spec/active_record/turntable/algorithm/modulo_algorithm_spec.rb +0 -34
- data/spec/active_record/turntable/algorithm/range_algorithm_spec.rb +0 -34
- data/spec/active_record/turntable/algorithm/range_bsearch_algorithm_spec.rb +0 -34
- data/spec/active_record/turntable/algorithm_spec.rb +0 -100
- data/spec/active_record/turntable/base_spec.rb +0 -13
- data/spec/active_record/turntable/cluster_spec.rb +0 -48
- data/spec/active_record/turntable/config_spec.rb +0 -17
- data/spec/active_record/turntable/connection_proxy_spec.rb +0 -252
- data/spec/active_record/turntable/finder_spec.rb +0 -40
- data/spec/active_record/turntable/mixer/fader_spec.rb +0 -4
- data/spec/active_record/turntable/mixer_spec.rb +0 -112
- data/spec/active_record/turntable/query_cache_spec.rb +0 -28
- data/spec/active_record/turntable/sequencer/api_spec.rb +0 -38
- data/spec/active_record/turntable/sequencer/barrage_spec.rb +0 -22
- data/spec/active_record/turntable/sequencer/mysql_spec.rb +0 -22
- data/spec/active_record/turntable/shard_spec.rb +0 -21
- data/spec/active_record/turntable/sql_tree_patch_spec.rb +0 -34
- data/spec/active_record/turntable/transaction_spec.rb +0 -35
- data/spec/active_record/turntable_spec.rb +0 -30
- data/spec/config/database.yml +0 -35
- data/spec/config/turntable.yml +0 -56
- data/spec/fabricators/.gitkeep +0 -0
- data/spec/fabricators/turntable_fabricator.rb +0 -12
- data/spec/fixtures/cards.yml +0 -11
- data/spec/migrations/.gitkeep +0 -0
- data/spec/migrations/001_create_users.rb +0 -17
- data/spec/migrations/002_create_user_statuses.rb +0 -16
- data/spec/migrations/003_create_cards.rb +0 -14
- data/spec/migrations/004_create_cards_users.rb +0 -15
- data/spec/models/card.rb +0 -3
- data/spec/models/cards_user.rb +0 -10
- data/spec/models/cards_users_histories.rb +0 -7
- data/spec/models/events_users_history.rb +0 -7
- data/spec/models/user.rb +0 -7
- data/spec/models/user_status.rb +0 -6
- data/spec/spec_helper.rb +0 -38
- data/spec/support/matchers/be_saved_to.rb +0 -6
- data/spec/support/turntable_helper.rb +0 -30
|
@@ -1,252 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe ActiveRecord::Turntable::ConnectionProxy do
|
|
4
|
-
before(:all) do
|
|
5
|
-
reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
context "When initialized" do
|
|
9
|
-
before do
|
|
10
|
-
establish_connection_to(:test)
|
|
11
|
-
truncate_shard
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
let(:cluster) { ActiveRecord::Turntable::Cluster.new(ActiveRecord::Base.turntable_config[:clusters][:user_cluster]) }
|
|
15
|
-
subject { ActiveRecord::Turntable::ConnectionProxy.new(User, cluster) }
|
|
16
|
-
|
|
17
|
-
its(:master_connection) { is_expected.to eql(ActiveRecord::Base.connection) }
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
context "User insert with id" do
|
|
21
|
-
before do
|
|
22
|
-
establish_connection_to(:test)
|
|
23
|
-
truncate_shard
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it "should be saved to user_shard_1 with id = 1" do
|
|
27
|
-
user = User.new
|
|
28
|
-
user.id = 1
|
|
29
|
-
expect {
|
|
30
|
-
user.save!
|
|
31
|
-
}.not_to raise_error
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
it "should be saved to user_shard_2 with id = 30000" do
|
|
35
|
-
user = User.new
|
|
36
|
-
user.id = 30000
|
|
37
|
-
expect {
|
|
38
|
-
user.save!
|
|
39
|
-
}.not_to raise_error
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it "should be saved to user_shard_2 with id = 30000 with SQL injection attack" do
|
|
43
|
-
user = User.new
|
|
44
|
-
user.id = 30000
|
|
45
|
-
user.nickname = "hogehgoge'00"
|
|
46
|
-
expect {
|
|
47
|
-
user.save!
|
|
48
|
-
}.not_to raise_error
|
|
49
|
-
user.reload
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
it "should should be saved the same string when includes escaped string" do
|
|
53
|
-
user = User.new
|
|
54
|
-
user.id = 30000
|
|
55
|
-
user.nickname = "hoge@\n@\\@@\\nhoge\\\nhoge\\n"
|
|
56
|
-
user.save!
|
|
57
|
-
user.reload
|
|
58
|
-
expect(user.nickname).to eq("hoge@\n@\\@@\\nhoge\\\nhoge\\n")
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
context "When have no users" do
|
|
63
|
-
before do
|
|
64
|
-
establish_connection_to(:test)
|
|
65
|
-
truncate_shard
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it "User.#count should be zero" do
|
|
69
|
-
expect(User.count).to be_zero
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
it "User.all should have no item" do
|
|
73
|
-
expect(User.all.to_a).to have(0).items
|
|
74
|
-
end
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
context "When have 2 Users in different shards" do
|
|
78
|
-
before do
|
|
79
|
-
establish_connection_to(:test)
|
|
80
|
-
truncate_shard
|
|
81
|
-
@user1 = User.new
|
|
82
|
-
@user1.id = 1
|
|
83
|
-
@user1.save!
|
|
84
|
-
@user2 = User.new
|
|
85
|
-
@user2.id = 30000
|
|
86
|
-
@user2.save!
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
it "should be saved to user_shard_1 with id = 1" do
|
|
90
|
-
@user1.nickname = "foobar"
|
|
91
|
-
expect {
|
|
92
|
-
@user1.save!
|
|
93
|
-
}.not_to raise_error
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
it "should be saved to user_shard_2 with id = 30000" do
|
|
97
|
-
@user2.nickname = "hogehoge"
|
|
98
|
-
expect {
|
|
99
|
-
@user2.save!
|
|
100
|
-
}.not_to raise_error
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
it "User.where('id IN (1, 30000)') returns 2 record" do
|
|
104
|
-
expect(User.where(id: [1, 30000]).all.size).to eq(2)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
it "count should be 2" do
|
|
108
|
-
expect(User.count).to eq(2)
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
it "User.all returns 2 User object" do
|
|
112
|
-
expect(User.all.size).to eq(2)
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
context "When calling with_all" do
|
|
117
|
-
before do
|
|
118
|
-
establish_connection_to(:test)
|
|
119
|
-
truncate_shard
|
|
120
|
-
@user1 = User.new
|
|
121
|
-
@user1.id = 1
|
|
122
|
-
@user1.nickname = "user1"
|
|
123
|
-
@user1.save!
|
|
124
|
-
@user2 = User.new
|
|
125
|
-
@user2.id = 30000
|
|
126
|
-
@user2.nickname = "user2"
|
|
127
|
-
@user2.save!
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
context "do; User.count; end" do
|
|
131
|
-
subject {
|
|
132
|
-
User.connection.with_all do
|
|
133
|
-
User.count
|
|
134
|
-
end
|
|
135
|
-
}
|
|
136
|
-
it { is_expected.to have(3).items }
|
|
137
|
-
|
|
138
|
-
it "returns User.count of each shards" do
|
|
139
|
-
expect(subject[0]).to eq(1)
|
|
140
|
-
expect(subject[1]).to eq(1)
|
|
141
|
-
expect(subject[2]).to eq(0)
|
|
142
|
-
end
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
context "call with true" do
|
|
146
|
-
context "block raises error" do
|
|
147
|
-
subject {
|
|
148
|
-
User.connection.with_all(true) do
|
|
149
|
-
raise "Unko Error"
|
|
150
|
-
end
|
|
151
|
-
}
|
|
152
|
-
it { expect { subject }.not_to raise_error }
|
|
153
|
-
it { is_expected.to have(3).items }
|
|
154
|
-
it "collection " do
|
|
155
|
-
subject.each do |s|
|
|
156
|
-
expect(s).to be_instance_of(RuntimeError)
|
|
157
|
-
end
|
|
158
|
-
end
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
end
|
|
162
|
-
|
|
163
|
-
context "When calling exists? with shard_key" do
|
|
164
|
-
before do
|
|
165
|
-
establish_connection_to(:test)
|
|
166
|
-
truncate_shard
|
|
167
|
-
@user1 = User.new
|
|
168
|
-
@user1.id = 1
|
|
169
|
-
@user1.nickname = "user1"
|
|
170
|
-
@user1.save!
|
|
171
|
-
@user2 = User.new
|
|
172
|
-
@user2.id = 30000
|
|
173
|
-
@user2.nickname = "user2"
|
|
174
|
-
@user2.save!
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
subject { User.exists?(id: 1) }
|
|
178
|
-
it { is_expected.to be_truthy }
|
|
179
|
-
end
|
|
180
|
-
|
|
181
|
-
context "When calling exists? with non-existed shard_key" do
|
|
182
|
-
before do
|
|
183
|
-
establish_connection_to(:test)
|
|
184
|
-
truncate_shard
|
|
185
|
-
@user1 = User.new
|
|
186
|
-
@user1.id = 1
|
|
187
|
-
@user1.nickname = "user1"
|
|
188
|
-
@user1.save!
|
|
189
|
-
@user2 = User.new
|
|
190
|
-
@user2.id = 30000
|
|
191
|
-
@user2.nickname = "user2"
|
|
192
|
-
@user2.save!
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
subject { User.exists?(id: 3) }
|
|
196
|
-
it { is_expected.to be_falsey }
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
context "When calling exists? with non shard_key" do
|
|
200
|
-
before do
|
|
201
|
-
establish_connection_to(:test)
|
|
202
|
-
truncate_shard
|
|
203
|
-
@user1 = User.new
|
|
204
|
-
@user1.id = 1
|
|
205
|
-
@user1.nickname = "user1"
|
|
206
|
-
@user1.save!
|
|
207
|
-
@user2 = User.new
|
|
208
|
-
@user2.id = 30000
|
|
209
|
-
@user2.nickname = "user2"
|
|
210
|
-
@user2.save!
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
subject { User.exists?(nickname: "user2") }
|
|
214
|
-
it { is_expected.to be_truthy }
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
context "When calling exists? with non-existed non shard_key" do
|
|
218
|
-
before do
|
|
219
|
-
establish_connection_to(:test)
|
|
220
|
-
truncate_shard
|
|
221
|
-
@user1 = User.new
|
|
222
|
-
@user1.id = 1
|
|
223
|
-
@user1.nickname = "user1"
|
|
224
|
-
@user1.save!
|
|
225
|
-
@user2 = User.new
|
|
226
|
-
@user2.id = 30000
|
|
227
|
-
@user2.nickname = "user2"
|
|
228
|
-
@user2.save!
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
subject { User.exists?(nickname: "user999") }
|
|
232
|
-
it { is_expected.to be_falsey }
|
|
233
|
-
end
|
|
234
|
-
|
|
235
|
-
context "#table_exists?" do
|
|
236
|
-
before do
|
|
237
|
-
establish_connection_to(:test)
|
|
238
|
-
truncate_shard
|
|
239
|
-
@user1 = User.new
|
|
240
|
-
@user1.id = 1
|
|
241
|
-
@user1.nickname = "user1"
|
|
242
|
-
@user1.save!
|
|
243
|
-
@user2 = User.new
|
|
244
|
-
@user2.id = 30000
|
|
245
|
-
@user2.nickname = "user2"
|
|
246
|
-
@user2.save!
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
subject { User.connection.table_exists?(:users) }
|
|
250
|
-
it { is_expected.to be_truthy }
|
|
251
|
-
end
|
|
252
|
-
end
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe "ActiveRecord::FinderMethods" do
|
|
4
|
-
before(:all) do
|
|
5
|
-
reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
context "User insert with id" do
|
|
9
|
-
before do
|
|
10
|
-
establish_connection_to(:test)
|
|
11
|
-
truncate_shard
|
|
12
|
-
user
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
let(:user) {
|
|
16
|
-
u = User.new
|
|
17
|
-
u.id = 1
|
|
18
|
-
u.save
|
|
19
|
-
u
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
describe "User#find" do
|
|
23
|
-
context "With existing users.id" do
|
|
24
|
-
subject { User.find(1) }
|
|
25
|
-
|
|
26
|
-
it "#find should be returns user" do
|
|
27
|
-
is_expected.to eq(user)
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
context "With users.id not existing" do
|
|
32
|
-
subject { User.find(2) }
|
|
33
|
-
|
|
34
|
-
it "#find should raise error" do
|
|
35
|
-
expect { subject }.to raise_error
|
|
36
|
-
end
|
|
37
|
-
end
|
|
38
|
-
end
|
|
39
|
-
end
|
|
40
|
-
end
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe ActiveRecord::Turntable::Mixer do
|
|
4
|
-
before(:all) do
|
|
5
|
-
reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
before do
|
|
9
|
-
establish_connection_to(:test)
|
|
10
|
-
truncate_shard
|
|
11
|
-
@cluster = ActiveRecord::Turntable::Cluster.new(ActiveRecord::Base.turntable_config[:clusters][:user_cluster])
|
|
12
|
-
@connection_proxy = ActiveRecord::Turntable::ConnectionProxy.new(User, @cluster)
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
context "When initialized" do
|
|
16
|
-
before do
|
|
17
|
-
@mixer = ActiveRecord::Turntable::Mixer.new(@connection_proxy)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
context "For Insert SQL" do
|
|
21
|
-
context "When call divide_insert_values with Single INSERT and shard_key 'id'" do
|
|
22
|
-
subject {
|
|
23
|
-
tree = SQLTree["INSERT INTO `users` (id, hp, mp) VALUES (1, 10, 10)"]
|
|
24
|
-
@mixer.send(:divide_insert_values, tree, "id")
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
it { is_expected.to be_instance_of(Hash) }
|
|
28
|
-
it { is_expected.to have_key(1) }
|
|
29
|
-
it { expect([1]).to have(1).item }
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
context "When call divide_insert_values with Bulk INSERT and shard_key 'id'" do
|
|
33
|
-
subject {
|
|
34
|
-
tree = SQLTree["INSERT INTO `users` (id, hp, mp) VALUES (1, 10, 10), (2,10,10), (3,10,10)"]
|
|
35
|
-
@mixer.send(:divide_insert_values, tree, "id")
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
it { is_expected.to be_instance_of(Hash) }
|
|
39
|
-
it { is_expected.to have_key(3) }
|
|
40
|
-
it { expect([1]).to have(1).item }
|
|
41
|
-
it { expect([2]).to have(1).item }
|
|
42
|
-
it { expect([3]).to have(1).item }
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
context "For Update SQL" do
|
|
47
|
-
context "When call find_shard_keys with eql shardkey condition" do
|
|
48
|
-
subject {
|
|
49
|
-
tree = SQLTree["UPDATE `users` SET `users`.`hp` = 20 WHERE `users`.`id` = 1"]
|
|
50
|
-
@mixer.find_shard_keys(tree.where, "users", "id")
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
it { is_expected.to be_instance_of Array }
|
|
54
|
-
it { is_expected.to eq([1]) }
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
context "For Delete SQL" do
|
|
59
|
-
context "When call find_shard_keys with eql shardkey condition" do
|
|
60
|
-
subject {
|
|
61
|
-
tree = SQLTree["DELETE FROM `users` WHERE `users`.`id` = 1"]
|
|
62
|
-
@mixer.find_shard_keys(tree.where, "users", "id")
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
it { is_expected.to be_instance_of Array }
|
|
66
|
-
it { is_expected.to eq([1]) }
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
context "For Select SQL" do
|
|
71
|
-
context "When call find_shard_keys with eql shardkey condition" do
|
|
72
|
-
subject {
|
|
73
|
-
tree = SQLTree["SELECT * FROM `users` WHERE `users`.`id` = 1"]
|
|
74
|
-
@mixer.find_shard_keys(tree.where, "users", "id")
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
it { is_expected.to be_instance_of Array }
|
|
78
|
-
it { is_expected.to eq([1]) }
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
context "When call find_shard_keys with shardkey collection condition" do
|
|
82
|
-
subject {
|
|
83
|
-
tree = SQLTree["SELECT * FROM `users` WHERE `users`.`id` IN (1,2,3,4,5)"]
|
|
84
|
-
@mixer.find_shard_keys(tree.where, "users", "id")
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
it { is_expected.to be_instance_of Array }
|
|
88
|
-
it { is_expected.to eq([1, 2, 3, 4, 5]) }
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
context "When call find_shard_keys with not determine shardkey condition" do
|
|
92
|
-
subject {
|
|
93
|
-
tree = SQLTree["SELECT * FROM `users` WHERE `users`.`id` = 1 OR 1"]
|
|
94
|
-
@mixer.find_shard_keys(tree.where, "users", "id")
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
it { is_expected.to be_instance_of Array }
|
|
98
|
-
it { is_expected.to eq([]) }
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
context "When call find_shard_keys with except table definition SQL" do
|
|
102
|
-
subject {
|
|
103
|
-
tree = SQLTree["SELECT * FROM `users` WHERE id = 10"]
|
|
104
|
-
@mixer.find_shard_keys(tree.where, "users", "id")
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
it { is_expected.to be_instance_of Array }
|
|
108
|
-
it { is_expected.to eq([]) }
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "active_support/executor"
|
|
3
|
-
|
|
4
|
-
describe ActiveRecord::Turntable::QueryCache do
|
|
5
|
-
before(:all) do
|
|
6
|
-
reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
before do
|
|
10
|
-
establish_connection_to(:test)
|
|
11
|
-
truncate_shard
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
let(:mw) {
|
|
15
|
-
executor = Class.new(ActiveSupport::Executor)
|
|
16
|
-
ActiveRecord::Turntable::QueryCache.install_executor_hooks executor
|
|
17
|
-
lambda { |env|
|
|
18
|
-
executor.wrap {
|
|
19
|
-
[200, {}, nil]
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
subject { mw.call({}) }
|
|
24
|
-
|
|
25
|
-
it "should returns 200 response" do
|
|
26
|
-
expect(subject.first).to eq(200)
|
|
27
|
-
end
|
|
28
|
-
end
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe ActiveRecord::Turntable::Sequencer::Api do
|
|
4
|
-
before(:all) do
|
|
5
|
-
reload_turntable!(File.join(File.dirname(__FILE__), "../../../config/turntable.yml"))
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
let(:sequencer) { ActiveRecord::Turntable::Sequencer::Api.new(klass, options) }
|
|
9
|
-
let(:sequence_name) { "hogefuga" }
|
|
10
|
-
let(:klass) { Class.new }
|
|
11
|
-
let(:api_host) { "example.example" }
|
|
12
|
-
let(:api_port) { 80 }
|
|
13
|
-
let(:options) { { api_host: api_host, api_port: api_port }.with_indifferent_access }
|
|
14
|
-
let(:api_response) { 1024 }
|
|
15
|
-
|
|
16
|
-
let(:next_sequence_uri) { "http://#{api_host}/sequences/#{sequence_name}/new" }
|
|
17
|
-
let(:current_sequence_uri) { "http://#{api_host}/sequences/#{sequence_name}" }
|
|
18
|
-
|
|
19
|
-
describe "#next_sequence_value" do
|
|
20
|
-
before do
|
|
21
|
-
stub_request(:get, next_sequence_uri).to_return(body: api_response.to_s)
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
subject { sequencer.next_sequence_value(sequence_name) }
|
|
25
|
-
it { is_expected.to be_kind_of(Integer) }
|
|
26
|
-
it { is_expected.to eq api_response }
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
describe "#current_sequence_value" do
|
|
30
|
-
before do
|
|
31
|
-
stub_request(:get, current_sequence_uri).to_return(body: api_response.to_s)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
subject { sequencer.current_sequence_value(sequence_name) }
|
|
35
|
-
it { is_expected.to be_kind_of(Integer) }
|
|
36
|
-
it { is_expected.to eq api_response }
|
|
37
|
-
end
|
|
38
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe ActiveRecord::Turntable::Sequencer::Barrage do
|
|
4
|
-
before(:all) do
|
|
5
|
-
reload_turntable!(File.join(File.dirname(__FILE__), "../../../config/turntable.yml"))
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
let(:sequencer) { ActiveRecord::Turntable::Sequencer::Barrage.new(klass, options) }
|
|
9
|
-
let(:sequence_name) { "hogefuga" }
|
|
10
|
-
let(:options) { { options: { generators: [{ name: "sequence", length: 16 }] } }.with_indifferent_access }
|
|
11
|
-
let(:klass) { Class.new }
|
|
12
|
-
|
|
13
|
-
describe "#next_sequence_value" do
|
|
14
|
-
subject { sequencer.next_sequence_value("hogefuga") }
|
|
15
|
-
it { is_expected.to be_kind_of(Integer) }
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
describe "#current_sequence_value" do
|
|
19
|
-
subject { sequencer.current_sequence_value("hogefuga") }
|
|
20
|
-
it { is_expected.to be_kind_of(Integer) }
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe ActiveRecord::Turntable::Sequencer::Mysql do
|
|
4
|
-
before(:all) do
|
|
5
|
-
reload_turntable!(File.join(File.dirname(__FILE__), "../../../config/turntable.yml"))
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
let(:sequencer) { ActiveRecord::Turntable::Sequencer::Mysql.new(klass, options) }
|
|
9
|
-
let(:sequence_name) { "users_id_seq" }
|
|
10
|
-
let(:options) { {} }
|
|
11
|
-
let(:klass) { User }
|
|
12
|
-
|
|
13
|
-
describe "#next_sequence_value" do
|
|
14
|
-
subject { sequencer.next_sequence_value(sequence_name) }
|
|
15
|
-
it { is_expected.to be_kind_of(Integer) }
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
describe "#current_sequence_value" do
|
|
19
|
-
subject { sequencer.current_sequence_value(sequence_name) }
|
|
20
|
-
it { is_expected.to be_kind_of(Integer) }
|
|
21
|
-
end
|
|
22
|
-
end
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe ActiveRecord::Turntable::Shard do
|
|
4
|
-
before(:all) do
|
|
5
|
-
reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
context "When initialized" do
|
|
9
|
-
before do
|
|
10
|
-
establish_connection_to(:test)
|
|
11
|
-
truncate_shard
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
subject {
|
|
15
|
-
ActiveRecord::Turntable::Shard.new(ActiveRecord::Base.turntable_config[:clusters][:user_cluster][:shards][0])
|
|
16
|
-
}
|
|
17
|
-
its(:name) { should == ActiveRecord::Base.turntable_config[:clusters][:user_cluster][:shards][0][:connection] }
|
|
18
|
-
its(:connection) { should be_instance_of(ActiveRecord::ConnectionAdapters::Mysql2Adapter) }
|
|
19
|
-
its(:connection_pool) { should be_instance_of(ActiveRecord::ConnectionAdapters::ConnectionPool) }
|
|
20
|
-
end
|
|
21
|
-
end
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
require "active_record/turntable/sql_tree_patch"
|
|
3
|
-
|
|
4
|
-
describe SQLTree do
|
|
5
|
-
before(:all) do
|
|
6
|
-
reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
context "Insert query with binary string" do
|
|
10
|
-
subject { SQLTree["INSERT INTO `hogehoge` (`name`) VALUES (x'deadbeef')"] }
|
|
11
|
-
it { expect { subject }.to_not raise_error }
|
|
12
|
-
its(:to_sql) { is_expected.to include("x'deadbeef") }
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
context "Select query with index hint" do
|
|
16
|
-
["FORCE INDEX", "IGNORE INDEX", "USE INDEX"].each do |hint|
|
|
17
|
-
context hint do
|
|
18
|
-
subject { SQLTree["SELECT * FROM table #{hint} (`foo`) WHERE field = 'value'"] }
|
|
19
|
-
it { expect { subject }.to_not raise_error }
|
|
20
|
-
its(:to_sql) { is_expected.to include("#{hint} (`foo`)") }
|
|
21
|
-
end
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
context "Select query without index hint" do
|
|
26
|
-
subject { SQLTree["SELECT * FROM table WHERE field = 'value'"] }
|
|
27
|
-
it { expect { subject }.to_not raise_error }
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
context "Delete query" do
|
|
31
|
-
subject { SQLTree["DELETE FROM table"] }
|
|
32
|
-
it { expect { subject }.to_not raise_error }
|
|
33
|
-
end
|
|
34
|
-
end
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe "transaction" do
|
|
4
|
-
before(:all) do
|
|
5
|
-
reload_turntable!(File.join(File.dirname(__FILE__), "../../config/turntable.yml"))
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
before(:each) do
|
|
9
|
-
establish_connection_to(:test)
|
|
10
|
-
truncate_shard
|
|
11
|
-
end
|
|
12
|
-
let(:clusters) { ActiveRecord::Base.turntable_clusters }
|
|
13
|
-
|
|
14
|
-
describe "all_cluster_transaction" do
|
|
15
|
-
let(:all_clusters) { clusters.values }
|
|
16
|
-
let(:shards) { all_clusters.flat_map { |c| c.shards.values } }
|
|
17
|
-
|
|
18
|
-
it "all shards should begin transaction" do
|
|
19
|
-
User.all_cluster_transaction {
|
|
20
|
-
expect(shards.map(&:connection).map(&:open_transactions)).to all(be == 1)
|
|
21
|
-
}
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
describe "cluster_transaction" do
|
|
26
|
-
let(:cluster) { clusters[:user_cluster] }
|
|
27
|
-
let(:shards) { cluster.shards.values }
|
|
28
|
-
|
|
29
|
-
it "all shards in the cluster should begin transaction" do
|
|
30
|
-
User.user_cluster_transaction {
|
|
31
|
-
expect(shards.map(&:connection).map(&:open_transactions)).to all(be == 1)
|
|
32
|
-
}
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
require "spec_helper"
|
|
2
|
-
|
|
3
|
-
describe ActiveRecord::Turntable do
|
|
4
|
-
before(:all) do
|
|
5
|
-
ActiveRecord::Base.include(ActiveRecord::Turntable)
|
|
6
|
-
end
|
|
7
|
-
|
|
8
|
-
context "#config_file" do
|
|
9
|
-
it "should return Rails.root/config/turntable.yml default" do
|
|
10
|
-
unless defined?(::Rails); class ::Rails; end; end
|
|
11
|
-
allow(Rails).to receive(:root) { "/path/to/rails_root" }
|
|
12
|
-
ActiveRecord::Base.turntable_config_file = nil
|
|
13
|
-
expect(ActiveRecord::Base.turntable_config_file).to eq("/path/to/rails_root/config/turntable.yml")
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
context "#config_file=" do
|
|
18
|
-
it "should set config_file" do
|
|
19
|
-
ActiveRecord::Base.include(ActiveRecord::Turntable)
|
|
20
|
-
filename = "hogefuga"
|
|
21
|
-
ActiveRecord::Base.turntable_config_file = filename
|
|
22
|
-
expect(ActiveRecord::Base.turntable_config_file).to eq(filename)
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
context "#config" do
|
|
27
|
-
subject { ActiveRecord::Base.turntable_config }
|
|
28
|
-
it { is_expected.to be_instance_of(ActiveRecord::Turntable::Config) }
|
|
29
|
-
end
|
|
30
|
-
end
|
data/spec/config/database.yml
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
default: &default
|
|
2
|
-
adapter: mysql2
|
|
3
|
-
username: root
|
|
4
|
-
password:
|
|
5
|
-
host: localhost
|
|
6
|
-
port: 3306
|
|
7
|
-
encoding: utf8
|
|
8
|
-
database: turntable_test
|
|
9
|
-
|
|
10
|
-
test:
|
|
11
|
-
<<: *default
|
|
12
|
-
database: turntable_test
|
|
13
|
-
seq:
|
|
14
|
-
user_seq:
|
|
15
|
-
<<: *default
|
|
16
|
-
database: turntable_user_seq_test
|
|
17
|
-
shards:
|
|
18
|
-
user_shard_1:
|
|
19
|
-
<<: *default
|
|
20
|
-
database: turntable_user_shard_1_test
|
|
21
|
-
user_shard_2:
|
|
22
|
-
<<: *default
|
|
23
|
-
database: turntable_user_shard_2_test
|
|
24
|
-
user_shard_3:
|
|
25
|
-
<<: *default
|
|
26
|
-
database: turntable_user_shard_3_test
|
|
27
|
-
user_shard_4:
|
|
28
|
-
<<: *default
|
|
29
|
-
database: turntable_user_shard_4_test
|
|
30
|
-
user_shard_5:
|
|
31
|
-
<<: *default
|
|
32
|
-
database: turntable_user_shard_5_test
|
|
33
|
-
user_shard_6:
|
|
34
|
-
<<: *default
|
|
35
|
-
database: turntable_user_shard_6_test
|