active_record_shards 2.5.3 → 2.5.4
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.
- data/lib/active_record_shards/finder_overrides.rb +56 -7
- data/test/configuration_parser_test.rb +10 -5
- data/test/connection_switching_test.rb +32 -29
- data/test/test.log +87286 -9815
- metadata +37 -9
@@ -1,25 +1,74 @@
|
|
1
1
|
module ActiveRecordShards
|
2
2
|
module FinderOverrides
|
3
|
-
|
3
|
+
CLASS_SLAVE_METHODS = [ :find_by_sql, :count_by_sql, :calculate, :find_one, :find_some, :find_every, :quote_value, :columns, :sanitize_sql_hash_for_conditions ]
|
4
|
+
|
4
5
|
def self.extended(base)
|
5
|
-
|
6
|
+
CLASS_SLAVE_METHODS.each do |slave_method|
|
6
7
|
base.class_eval <<-EOF, __FILE__, __LINE__ + 1
|
7
8
|
class <<self
|
8
|
-
def #{slave_method}
|
9
|
+
def #{slave_method}_with_default_slave(*args, &block)
|
9
10
|
on_slave_unless_tx do
|
10
|
-
#{slave_method}
|
11
|
+
#{slave_method}_without_default_slave(*args, &block)
|
11
12
|
end
|
12
13
|
end
|
13
14
|
|
14
|
-
alias_method_chain :#{slave_method}, :
|
15
|
+
alias_method_chain :#{slave_method}, :default_slave if respond_to?(:#{slave_method})
|
15
16
|
end
|
16
17
|
EOF
|
17
18
|
end
|
19
|
+
|
20
|
+
base.class_eval do
|
21
|
+
# fix ActiveRecord to do the right thing, and use our aliased quote_value
|
22
|
+
def quote_value(*args, &block)
|
23
|
+
self.class.quote_value(*args, &block)
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def transaction_with_slave_off(*args, &block)
|
28
|
+
if on_slave_by_default?
|
29
|
+
old_val = Thread.current[:_active_record_shards_slave_off]
|
30
|
+
Thread.current[:_active_record_shards_slave_off] = true
|
31
|
+
end
|
32
|
+
|
33
|
+
transaction_without_slave_off(*args, &block)
|
34
|
+
ensure
|
35
|
+
if on_slave_by_default?
|
36
|
+
Thread.current[:_active_record_shards_slave_off] = old_val
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
alias_method_chain :transaction, :slave_off
|
41
|
+
|
42
|
+
|
43
|
+
def table_exists_with_default_slave?(*args)
|
44
|
+
on_slave_unless_tx(*args) { table_exists_without_default_slave?(*args) }
|
45
|
+
end
|
46
|
+
|
47
|
+
alias_method_chain :table_exists?, :default_slave
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
|
52
|
+
ActiveRecord::Associations::HasAndBelongsToManyAssociation.class_eval do
|
53
|
+
def construct_sql_with_default_slave(*args, &block)
|
54
|
+
on_slave_unless_tx do
|
55
|
+
construct_sql_without_default_slave(*args, &block)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def construct_find_options_with_default_slave!(*args, &block)
|
60
|
+
on_slave_unless_tx do
|
61
|
+
construct_find_options_without_default_slave!(*args, &block)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
alias_method_chain :construct_sql, :default_slave if respond_to?(:construct_sql)
|
66
|
+
alias_method_chain :construct_find_options!, :default_slave if respond_to?(:construct_find_options!)
|
67
|
+
end
|
18
68
|
end
|
19
69
|
|
20
|
-
private
|
21
70
|
def on_slave_unless_tx(&block)
|
22
|
-
if on_slave_by_default? &&
|
71
|
+
if on_slave_by_default? && !Thread.current[:_active_record_shards_slave_off]
|
23
72
|
on_slave { yield }
|
24
73
|
else
|
25
74
|
yield
|
@@ -9,6 +9,7 @@ class ConfigurationParserTest < ActiveSupport::TestCase
|
|
9
9
|
context "main slave" do
|
10
10
|
setup { @conf = @exploded_conf['test_slave'] }
|
11
11
|
should "be exploded" do
|
12
|
+
@conf["shard_names"] = @conf["shard_names"].to_set
|
12
13
|
assert_equal({
|
13
14
|
"adapter" => "mysql",
|
14
15
|
"encoding" => "utf8",
|
@@ -17,7 +18,7 @@ class ConfigurationParserTest < ActiveSupport::TestCase
|
|
17
18
|
"username" => "root",
|
18
19
|
"password" => nil,
|
19
20
|
"host" => "main_slave_host",
|
20
|
-
"shard_names" => ["a", "b"]
|
21
|
+
"shard_names" => ["a", "b"].to_set
|
21
22
|
}, @conf)
|
22
23
|
end
|
23
24
|
end
|
@@ -26,6 +27,7 @@ class ConfigurationParserTest < ActiveSupport::TestCase
|
|
26
27
|
context "master" do
|
27
28
|
setup { @conf = @exploded_conf['test_shard_a'] }
|
28
29
|
should "be exploded" do
|
30
|
+
@conf["shard_names"] = @conf["shard_names"].to_set
|
29
31
|
assert_equal({
|
30
32
|
"adapter" => "mysql",
|
31
33
|
"encoding" => "utf8",
|
@@ -34,7 +36,7 @@ class ConfigurationParserTest < ActiveSupport::TestCase
|
|
34
36
|
"username" => "root",
|
35
37
|
"password" => nil,
|
36
38
|
"host" => "shard_a_host",
|
37
|
-
"shard_names" => ["a", "b"]
|
39
|
+
"shard_names" => ["a", "b"].to_set
|
38
40
|
}, @conf)
|
39
41
|
end
|
40
42
|
end
|
@@ -42,6 +44,7 @@ class ConfigurationParserTest < ActiveSupport::TestCase
|
|
42
44
|
context "slave" do
|
43
45
|
setup { @conf = @exploded_conf['test_shard_a_slave'] }
|
44
46
|
should "be exploded" do
|
47
|
+
@conf["shard_names"] = @conf["shard_names"].to_set
|
45
48
|
assert_equal({
|
46
49
|
"adapter" => "mysql",
|
47
50
|
"encoding" => "utf8",
|
@@ -50,7 +53,7 @@ class ConfigurationParserTest < ActiveSupport::TestCase
|
|
50
53
|
"username" => "root",
|
51
54
|
"password" => nil,
|
52
55
|
"host" => "shard_a_slave_host",
|
53
|
-
"shard_names" => ["a", "b"]
|
56
|
+
"shard_names" => ["a", "b"].to_set
|
54
57
|
}, @conf)
|
55
58
|
end
|
56
59
|
end
|
@@ -60,6 +63,7 @@ class ConfigurationParserTest < ActiveSupport::TestCase
|
|
60
63
|
context "master" do
|
61
64
|
setup { @conf = @exploded_conf['test_shard_b'] }
|
62
65
|
should "be exploded" do
|
66
|
+
@conf["shard_names"] = @conf["shard_names"].to_set
|
63
67
|
assert_equal({
|
64
68
|
"adapter" => "mysql",
|
65
69
|
"encoding" => "utf8",
|
@@ -68,7 +72,7 @@ class ConfigurationParserTest < ActiveSupport::TestCase
|
|
68
72
|
"username" => "root",
|
69
73
|
"password" => nil,
|
70
74
|
"host" => "shard_b_host",
|
71
|
-
"shard_names" => ["a", "b"]
|
75
|
+
"shard_names" => ["a", "b"].to_set
|
72
76
|
}, @conf)
|
73
77
|
end
|
74
78
|
end
|
@@ -76,6 +80,7 @@ class ConfigurationParserTest < ActiveSupport::TestCase
|
|
76
80
|
context "slave" do
|
77
81
|
setup { @conf = @exploded_conf['test_shard_b_slave'] }
|
78
82
|
should "be exploded" do
|
83
|
+
@conf["shard_names"] = @conf["shard_names"].to_set
|
79
84
|
assert_equal({
|
80
85
|
"adapter" => "mysql",
|
81
86
|
"encoding" => "utf8",
|
@@ -84,7 +89,7 @@ class ConfigurationParserTest < ActiveSupport::TestCase
|
|
84
89
|
"username" => "root",
|
85
90
|
"password" => nil,
|
86
91
|
"host" => "shard_b_host",
|
87
|
-
"shard_names" => ["a", "b"]
|
92
|
+
"shard_names" => ["a", "b"].to_set
|
88
93
|
}, @conf)
|
89
94
|
end
|
90
95
|
end
|
@@ -352,41 +352,44 @@ class ConnectionSwitchenTest < ActiveSupport::TestCase
|
|
352
352
|
end
|
353
353
|
end
|
354
354
|
|
355
|
-
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
355
|
+
# TODO: make all this stuff rails 3 compatible.
|
356
|
+
if Gem.loaded_specs['activerecord'].version < Gem::Version.create('3.0')
|
357
|
+
context "with finds routed to the slave by default" do
|
358
|
+
setup do
|
359
|
+
Account.on_slave_by_default = true
|
360
|
+
Account.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1000, 'master_name', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
|
361
|
+
Account.on_slave.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1000, 'slave_name', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
|
362
|
+
Account.on_slave.connection.execute("INSERT INTO accounts (id, name, created_at, updated_at) VALUES(1001, 'slave_name2', '2009-12-04 20:18:48', '2009-12-04 20:18:48')")
|
363
|
+
end
|
362
364
|
|
363
|
-
|
364
|
-
|
365
|
-
|
366
|
-
|
365
|
+
should "find() by default on the slave" do
|
366
|
+
account = Account.find(1000)
|
367
|
+
assert_equal 'slave_name', account.name
|
368
|
+
end
|
367
369
|
|
368
|
-
|
369
|
-
|
370
|
-
|
371
|
-
|
370
|
+
should "count() by default on the slave" do
|
371
|
+
count = Account.all.size
|
372
|
+
assert_equal 2, count
|
373
|
+
end
|
372
374
|
|
373
|
-
|
374
|
-
|
375
|
-
|
376
|
-
|
375
|
+
should "Allow override using on_master" do
|
376
|
+
model = Account.on_master.find(1000)
|
377
|
+
assert_equal "master_name", model.name
|
378
|
+
end
|
377
379
|
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
380
|
+
should "not override on_master with on_slave" do
|
381
|
+
model = Account.on_master { Account.on_slave.find(1000) }
|
382
|
+
assert_equal "master_name", model.name
|
383
|
+
end
|
382
384
|
|
383
|
-
|
384
|
-
|
385
|
-
|
386
|
-
|
385
|
+
should "override on_slave with on_master" do
|
386
|
+
model = Account.on_slave { Account.on_master.find(1000) }
|
387
|
+
assert_equal "master_name", model.name
|
388
|
+
end
|
387
389
|
|
388
|
-
|
389
|
-
|
390
|
+
teardown do
|
391
|
+
Account.on_slave_by_default = false
|
392
|
+
end
|
390
393
|
end
|
391
394
|
end
|
392
395
|
end
|