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.
@@ -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