active_record_shards 2.5.3 → 2.5.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,25 +1,74 @@
1
1
  module ActiveRecordShards
2
2
  module FinderOverrides
3
- SLAVE_METHODS = [ :find_by_sql, :count_by_sql, :calculate ]
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
- SLAVE_METHODS.each do |slave_method|
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}_with_slave_by_default(*args, &block)
9
+ def #{slave_method}_with_default_slave(*args, &block)
9
10
  on_slave_unless_tx do
10
- #{slave_method}_without_slave_by_default(*args, &block)
11
+ #{slave_method}_without_default_slave(*args, &block)
11
12
  end
12
13
  end
13
14
 
14
- alias_method_chain :#{slave_method}, :slave_by_default
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? && on_master.connection.open_transactions.zero?
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
- context "with finds routed to the slave by default" do
356
- setup do
357
- Account.on_slave_by_default = true
358
- 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')")
359
- 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')")
360
- 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')")
361
- end
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
- should "find() by default on the slave" do
364
- account = Account.find(1000)
365
- assert_equal 'slave_name', account.name
366
- end
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
- should "count() by default on the slave" do
369
- count = Account.all.size
370
- assert_equal 2, count
371
- end
370
+ should "count() by default on the slave" do
371
+ count = Account.all.size
372
+ assert_equal 2, count
373
+ end
372
374
 
373
- should "Allow override using on_master" do
374
- model = Account.on_master.find(1000)
375
- assert_equal "master_name", model.name
376
- end
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
- should "not override on_master with on_slave" do
379
- model = Account.on_master { Account.on_slave.find(1000) }
380
- assert_equal "master_name", model.name
381
- end
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
- should "override on_slave with on_master" do
384
- model = Account.on_slave { Account.on_master.find(1000) }
385
- assert_equal "master_name", model.name
386
- end
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
- teardown do
389
- Account.on_slave_by_default = false
390
+ teardown do
391
+ Account.on_slave_by_default = false
392
+ end
390
393
  end
391
394
  end
392
395
  end