ar-octopus 0.8.1 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +6 -14
  2. data/.gitignore +1 -0
  3. data/.rspec +1 -1
  4. data/.rubocop.yml +46 -0
  5. data/.rubocop_todo.yml +56 -0
  6. data/.travis.yml +7 -12
  7. data/Appraisals +11 -4
  8. data/Gemfile +1 -1
  9. data/README.mkdn +138 -63
  10. data/Rakefile +23 -16
  11. data/ar-octopus.gemspec +23 -20
  12. data/gemfiles/rails42.gemfile +7 -0
  13. data/gemfiles/{rails32.gemfile → rails5.gemfile} +2 -2
  14. data/gemfiles/{rails4.gemfile → rails51.gemfile} +2 -2
  15. data/gemfiles/rails52.gemfile +7 -0
  16. data/lib/ar-octopus.rb +1 -1
  17. data/lib/octopus/{rails3/abstract_adapter.rb → abstract_adapter.rb} +4 -15
  18. data/lib/octopus/association.rb +8 -99
  19. data/lib/octopus/association_shard_tracking.rb +74 -0
  20. data/lib/octopus/collection_association.rb +17 -0
  21. data/lib/octopus/collection_proxy.rb +16 -0
  22. data/lib/octopus/exception.rb +4 -0
  23. data/lib/octopus/finder_methods.rb +8 -0
  24. data/lib/octopus/load_balancing/round_robin.rb +20 -0
  25. data/lib/octopus/load_balancing.rb +4 -0
  26. data/lib/octopus/{rails3/log_subscriber.rb → log_subscriber.rb} +6 -2
  27. data/lib/octopus/migration.rb +187 -110
  28. data/lib/octopus/model.rb +151 -131
  29. data/lib/octopus/persistence.rb +45 -0
  30. data/lib/octopus/proxy.rb +297 -232
  31. data/lib/octopus/proxy_config.rb +251 -0
  32. data/lib/octopus/query_cache_for_shards.rb +24 -0
  33. data/lib/octopus/railtie.rb +1 -3
  34. data/lib/octopus/relation_proxy.rb +70 -0
  35. data/lib/octopus/result_patch.rb +19 -0
  36. data/lib/octopus/scope_proxy.rb +54 -36
  37. data/lib/octopus/shard_tracking/attribute.rb +22 -0
  38. data/lib/octopus/shard_tracking/dynamic.rb +11 -0
  39. data/lib/octopus/shard_tracking.rb +46 -0
  40. data/lib/octopus/singular_association.rb +9 -0
  41. data/lib/octopus/slave_group.rb +13 -0
  42. data/lib/octopus/version.rb +1 -1
  43. data/lib/octopus.rb +125 -33
  44. data/lib/tasks/octopus.rake +2 -2
  45. data/sample_app/Gemfile +3 -3
  46. data/sample_app/autotest/discover.rb +2 -2
  47. data/sample_app/config/application.rb +1 -1
  48. data/sample_app/config/boot.rb +1 -1
  49. data/sample_app/config/environments/test.rb +1 -1
  50. data/sample_app/config/initializers/session_store.rb +1 -1
  51. data/sample_app/config/initializers/wrap_parameters.rb +1 -1
  52. data/sample_app/config/routes.rb +1 -1
  53. data/sample_app/db/migrate/20100720210335_create_sample_users.rb +2 -2
  54. data/sample_app/db/schema.rb +10 -10
  55. data/sample_app/db/seeds.rb +3 -3
  56. data/sample_app/features/step_definitions/seeds_steps.rb +4 -4
  57. data/sample_app/features/step_definitions/web_steps.rb +3 -4
  58. data/sample_app/features/support/env.rb +3 -4
  59. data/sample_app/features/support/paths.rb +4 -4
  60. data/sample_app/lib/tasks/cucumber.rake +43 -44
  61. data/sample_app/spec/spec_helper.rb +3 -3
  62. data/spec/config/shards.yml +78 -0
  63. data/spec/migrations/10_create_users_using_replication.rb +4 -4
  64. data/spec/migrations/11_add_field_in_all_slaves.rb +4 -4
  65. data/spec/migrations/12_create_users_using_block.rb +8 -8
  66. data/spec/migrations/13_create_users_using_block_and_using.rb +5 -5
  67. data/spec/migrations/14_create_users_on_shards_of_a_group_with_versions.rb +3 -3
  68. data/spec/migrations/15_create_user_on_shards_of_default_group_with_versions.rb +3 -3
  69. data/spec/migrations/1_create_users_on_master.rb +4 -4
  70. data/spec/migrations/2_create_users_on_canada.rb +4 -4
  71. data/spec/migrations/3_create_users_on_both_shards.rb +4 -4
  72. data/spec/migrations/4_create_users_on_shards_of_a_group.rb +4 -4
  73. data/spec/migrations/5_create_users_on_multiples_groups.rb +3 -3
  74. data/spec/migrations/6_raise_exception_with_invalid_shard_name.rb +4 -4
  75. data/spec/migrations/7_raise_exception_with_invalid_multiple_shard_names.rb +4 -4
  76. data/spec/migrations/8_raise_exception_with_invalid_group_name.rb +4 -4
  77. data/spec/migrations/9_raise_exception_with_multiple_invalid_group_names.rb +5 -5
  78. data/spec/octopus/association_shard_tracking_spec.rb +1036 -0
  79. data/spec/octopus/collection_proxy_spec.rb +16 -0
  80. data/spec/octopus/load_balancing/round_robin_spec.rb +15 -0
  81. data/spec/octopus/log_subscriber_spec.rb +5 -5
  82. data/spec/octopus/migration_spec.rb +83 -49
  83. data/spec/octopus/model_spec.rb +544 -292
  84. data/spec/octopus/octopus_spec.rb +64 -31
  85. data/spec/octopus/proxy_spec.rb +145 -141
  86. data/spec/octopus/query_cache_for_shards_spec.rb +40 -0
  87. data/spec/octopus/relation_proxy_spec.rb +132 -0
  88. data/spec/octopus/replicated_slave_grouped_spec.rb +91 -0
  89. data/spec/octopus/replication_spec.rb +140 -65
  90. data/spec/octopus/scope_proxy_spec.rb +90 -10
  91. data/spec/octopus/sharded_replicated_slave_grouped_spec.rb +55 -0
  92. data/spec/octopus/sharded_spec.rb +10 -10
  93. data/spec/spec_helper.rb +8 -6
  94. data/spec/support/active_record/connection_adapters/modify_config_adapter.rb +1 -3
  95. data/spec/support/database_connection.rb +2 -2
  96. data/spec/support/database_models.rb +18 -17
  97. data/spec/support/octopus_helper.rb +32 -25
  98. data/spec/support/query_count.rb +1 -3
  99. data/spec/support/shared_contexts.rb +3 -3
  100. data/spec/tasks/octopus.rake_spec.rb +10 -10
  101. metadata +112 -70
  102. data/.ruby-version +0 -1
  103. data/init.rb +0 -1
  104. data/lib/octopus/association_collection.rb +0 -49
  105. data/lib/octopus/has_and_belongs_to_many_association.rb +0 -17
  106. data/lib/octopus/rails3/persistence.rb +0 -39
  107. data/lib/octopus/rails3/singular_association.rb +0 -34
  108. data/rails/init.rb +0 -1
  109. data/spec/octopus/association_spec.rb +0 -712
@@ -1,64 +1,63 @@
1
- require "spec_helper"
1
+ require 'spec_helper'
2
2
 
3
3
  describe Octopus, :shards => [] do
4
- describe "#config" do
5
- it "should load shards.yml file to start working" do
6
- Octopus.config().should be_kind_of(HashWithIndifferentAccess)
4
+ describe '#config' do
5
+ it 'should load shards.yml file to start working' do
6
+ expect(Octopus.config).to be_kind_of(HashWithIndifferentAccess)
7
7
  end
8
8
 
9
9
  describe "when config file doesn't exist" do
10
10
  before(:each) do
11
- Octopus.stub(:directory).and_return('/tmp')
11
+ allow(Octopus).to receive(:directory).and_return('/tmp')
12
12
  Octopus.instance_variable_set(:@config, nil)
13
13
  end
14
14
 
15
- it "should return an empty HashWithIndifferentAccess" do
16
- Octopus.config().should == HashWithIndifferentAccess.new
15
+ it 'should return an empty HashWithIndifferentAccess' do
16
+ expect(Octopus.config).to eq(HashWithIndifferentAccess.new)
17
17
  end
18
18
  end
19
19
  end
20
20
 
21
- describe "#directory" do
22
- it "should return the directory that contains the shards.yml file" do
23
- Octopus.directory().should == File.expand_path(File.dirname(__FILE__) + "/../")
21
+ describe '#directory' do
22
+ it 'should return the directory that contains the shards.yml file' do
23
+ expect(Octopus.directory).to eq(File.expand_path(File.dirname(__FILE__) + '/../'))
24
24
  end
25
25
  end
26
26
 
27
- describe "#env" do
27
+ describe '#env' do
28
28
  it "should return 'production' when is outside of a rails application" do
29
- Octopus.env().should == 'octopus'
29
+ expect(Octopus.env).to eq('octopus')
30
30
  end
31
31
  end
32
32
 
33
-
34
- describe "#shards=" do
33
+ describe '#shards=' do
35
34
  after(:each) do
36
35
  Octopus.instance_variable_set(:@config, nil)
37
36
  Octopus::Model.send(:class_variable_set, :@@connection_proxy, nil)
38
37
  end
39
38
 
40
- it "should permit users to configure shards on initializer files, instead of on a yml file." do
41
- lambda { User.using(:crazy_shard).create!(:name => "Joaquim") }.should raise_error
39
+ it 'should permit users to configure shards on initializer files, instead of on a yml file.' do
40
+ expect { User.using(:crazy_shard).create!(:name => 'Joaquim') }.to raise_error(RuntimeError)
42
41
 
43
42
  Octopus.setup do |config|
44
- config.shards = {:crazy_shard => {:adapter => "mysql2", :database => "octopus_shard_5", :username => "root", :password => ""}}
43
+ config.shards = { :crazy_shard => { :adapter => 'mysql2', :database => 'octopus_shard_5', :username => "#{ENV['MYSQL_USER'] || 'root'}", :password => '' } }
45
44
  end
46
45
 
47
- lambda { User.using(:crazy_shard).create!(:name => "Joaquim") }.should_not raise_error
46
+ expect { User.using(:crazy_shard).create!(:name => 'Joaquim') }.not_to raise_error
48
47
  end
49
48
  end
50
49
 
51
- describe "#setup" do
52
- it "should have the default octopus environment as production" do
53
- Octopus.environments.should == ["production"]
50
+ describe '#setup' do
51
+ it 'should have the default octopus environment as production' do
52
+ expect(Octopus.environments).to eq(['production'])
54
53
  end
55
54
 
56
- it "should allow the user to configure the octopus environments" do
55
+ it 'should allow the user to configure the octopus environments' do
57
56
  Octopus.setup do |config|
58
57
  config.environments = [:production, :staging]
59
58
  end
60
59
 
61
- Octopus.environments.should == ['production', 'staging']
60
+ expect(Octopus.environments).to eq(%w(production staging))
62
61
 
63
62
  Octopus.setup do |config|
64
63
  config.environments = [:production]
@@ -66,25 +65,59 @@ describe Octopus, :shards => [] do
66
65
  end
67
66
  end
68
67
 
69
- describe "#enabled?" do
68
+ describe '#enabled?' do
70
69
  before do
71
- Rails = double()
70
+ Rails = double
72
71
  end
73
72
 
74
73
  after do
75
74
  Object.send(:remove_const, :Rails)
76
75
  end
77
76
 
78
- it "should be if octopus is configured and should hook into current environment" do
79
- Rails.stub(:env).and_return('production')
77
+ it 'should be if octopus is configured and should hook into current environment' do
78
+ allow(Rails).to receive(:env).and_return('production')
79
+
80
+ expect(Octopus).to be_enabled
81
+ end
82
+
83
+ it 'should not be if octopus should not hook into current environment' do
84
+ allow(Rails).to receive(:env).and_return('staging')
85
+
86
+ expect(Octopus).not_to be_enabled
87
+ end
88
+ end
89
+
90
+ describe '#fully_replicated' do
91
+ before do
92
+ OctopusHelper.using_environment :production_replicated do
93
+ OctopusHelper.clean_all_shards([:slave1, :slave2, :slave3, :slave4])
94
+ 4.times { |i| User.using(:"slave#{i + 1}").create!(:name => 'Slave User') }
95
+ end
96
+ end
80
97
 
81
- Octopus.should be_enabled
98
+ it 'sends queries to slaves' do
99
+ OctopusHelper.using_environment :production_replicated do
100
+ expect(User.count).to eq(0)
101
+ 4.times do |_i|
102
+ Octopus.fully_replicated do
103
+ expect(User.count).to eq(1)
104
+ end
105
+ end
106
+ end
82
107
  end
83
108
 
84
- it "should not be if octopus should not hook into current environment" do
85
- Rails.stub(:env).and_return('staging')
109
+ it 'allows nesting' do
110
+ OctopusHelper.using_environment :production_replicated do
111
+ Octopus.fully_replicated do
112
+ expect(User.count).to eq(1)
113
+
114
+ Octopus.fully_replicated do
115
+ expect(User.count).to eq(1)
116
+ end
86
117
 
87
- Octopus.should_not be_enabled
118
+ expect(User.count).to eq(1)
119
+ end
120
+ end
88
121
  end
89
122
  end
90
123
  end
@@ -1,299 +1,303 @@
1
- require "spec_helper"
1
+ require 'spec_helper'
2
2
 
3
3
  describe Octopus::Proxy do
4
4
  let(:proxy) { subject }
5
5
 
6
- describe "creating a new instance", :shards => [] do
7
- it "should initialize all shards and groups" do
6
+ describe 'creating a new instance', :shards => [] do
7
+ it 'should initialize all shards and groups' do
8
8
  # FIXME: Don't test implementation details
9
- proxy.instance_variable_get(:@shards).should include("canada", "brazil", "master", "sqlite_shard", "russia", "alone_shard",
10
- "aug2009", "postgresql_shard", "aug2010", "aug2011")
9
+ expect(proxy.shards).to include('canada', 'brazil', 'master', 'sqlite_shard', 'russia', 'alone_shard',
10
+ 'aug2009', 'postgresql_shard', 'aug2010', 'aug2011')
11
11
 
12
- proxy.instance_variable_get(:@shards).should include("protocol_shard")
12
+ expect(proxy.shards).to include('protocol_shard')
13
13
 
14
- proxy.has_group?("country_shards").should be_true
15
- proxy.shards_for_group("country_shards").should include(:canada, :brazil, :russia)
14
+ expect(proxy.has_group?('country_shards')).to be true
15
+ expect(proxy.shards_for_group('country_shards')).to include(:canada, :brazil, :russia)
16
16
 
17
- proxy.has_group?("history_shards").should be_true
18
- proxy.shards_for_group("history_shards").should include(:aug2009, :aug2010, :aug2011)
17
+ expect(proxy.has_group?('history_shards')).to be true
18
+ expect(proxy.shards_for_group('history_shards')).to include(:aug2009, :aug2010, :aug2011)
19
19
  end
20
20
 
21
- it "should initialize the block attribute as false" do
22
- proxy.block.should be_false
21
+ it 'should initialize the block attribute as false' do
22
+ expect(proxy.block).to be_falsey
23
23
  end
24
24
 
25
- it "should initialize replicated attribute as false" do
26
- proxy.instance_variable_get(:@replicated).should be_false
25
+ it 'should initialize replicated attribute as false' do
26
+ expect(proxy.replicated).to be_falsey
27
27
  end
28
28
 
29
- it "should work with thiking sphinx" do
30
- config = proxy.instance_variable_get(:@config)
31
- config[:adapter].should == "mysql2"
32
- config[:database].should == "octopus_shard_1"
33
- config[:username].should == "root"
29
+ it 'should work with thinking sphinx' do
30
+ config = proxy.config
31
+ expect(config[:adapter]).to eq('mysql2')
32
+ expect(config[:database]).to eq('octopus_shard_1')
33
+ expect(config[:username]).to eq("#{ENV['MYSQL_USER'] || 'root'}")
34
34
  end
35
35
 
36
- it 'should create a set with all adapters, to ensure that is needed to clean the table name.' do
37
- adapters = proxy.instance_variable_get(:@adapters)
38
- adapters.should be_kind_of(Set)
39
- adapters.to_a.should =~ ["sqlite3", "mysql2", "postgresql"]
40
- end
41
-
42
- it 'should respond correctly to respond_to?(:pk_and_sequence_for)' do
43
- proxy.respond_to?(:pk_and_sequence_for).should be_true
36
+ unless Octopus.rails50? || Octopus.rails51?|| Octopus.rails52?
37
+ it 'should respond correctly to respond_to?(:pk_and_sequence_for)' do
38
+ expect(proxy.respond_to?(:pk_and_sequence_for)).to be true
39
+ end
44
40
  end
45
41
 
46
42
  it 'should respond correctly to respond_to?(:primary_key)' do
47
- proxy.respond_to?(:primary_key).should be_true
43
+ expect(proxy.respond_to?(:primary_key)).to be true
48
44
  end
49
45
 
50
46
  context 'when an adapter that modifies the config' do
51
- before(:all) { OctopusHelper.set_octopus_env("modify_config") }
52
- after(:all) { OctopusHelper.set_octopus_env("octopus") }
47
+ before { OctopusHelper.octopus_env = 'modify_config' }
48
+ after { OctopusHelper.octopus_env = 'octopus' }
53
49
 
54
50
  it 'should not fail with missing adapter second time round' do
55
- pending "This test was actually failing because of a typo in the error message."
56
- Thread.current["octopus.current_shard"] = :modify_config_read
51
+ skip 'This test was actually failing because of a typo in the error message.'
52
+ Thread.current['octopus.current_shard'] = :modify_config_read
57
53
 
58
- lambda { Octopus::Proxy.new(Octopus.config()) }.should_not raise_error
59
-
60
- Thread.current["octopus.current_shard"] = nil
61
- end
62
- end
54
+ expect { Octopus::Proxy.new(Octopus.config) }.not_to raise_error
63
55
 
64
- describe "#should_clean_table_name?" do
65
- it 'should return true when you have a environment with multiple database types' do
66
- proxy.should_clean_table_name?.should be_true
67
- end
68
-
69
- context "when using a environment with a single table name" do
70
- before(:each) do
71
- OctopusHelper.set_octopus_env("production_replicated")
72
- end
73
-
74
- it 'should return false' do
75
- proxy.should_clean_table_name?.should be_false
76
- end
56
+ Thread.current['octopus.current_shard'] = nil
77
57
  end
78
58
  end
79
59
 
80
- describe "should raise error if you have duplicated shard names" do
60
+ describe 'should raise error if you have duplicated shard names' do
81
61
  before(:each) do
82
- OctopusHelper.set_octopus_env("production_raise_error")
62
+ OctopusHelper.octopus_env = 'production_raise_error'
83
63
  end
84
64
 
85
- it "should raise the error" do
86
- lambda { proxy }.should raise_error("You have duplicated shard names!")
65
+ it 'should raise the error' do
66
+ expect { proxy }.to raise_error('You have duplicated shard names!')
87
67
  end
88
68
  end
89
69
 
90
70
  describe "should initialize just the master when you don't have a shards.yml file" do
91
71
  before(:each) do
92
- OctopusHelper.set_octopus_env("crazy_environment")
72
+ OctopusHelper.octopus_env = 'crazy_environment'
93
73
  end
94
74
 
95
- it "should initialize just the master shard" do
96
- proxy.instance_variable_get(:@shards).keys.should == ["master"]
75
+ it 'should initialize just the master shard' do
76
+ expect(proxy.shards.keys).to eq(['master'])
97
77
  end
98
78
 
99
- it "should not initialize replication" do
100
- proxy.instance_variable_get(:@replicated).should be_nil
79
+ it 'should not initialize replication' do
80
+ expect(proxy.replicated).to be_nil
101
81
  end
102
82
  end
103
83
  end
104
84
 
105
- describe "when you have a replicated environment" do
85
+ describe 'when you have a replicated environment' do
106
86
  before(:each) do
107
- OctopusHelper.set_octopus_env("production_replicated")
87
+ OctopusHelper.octopus_env = 'production_replicated'
108
88
  end
109
89
 
110
- it "should have the replicated attribute as true" do
111
- proxy.instance_variable_get(:@replicated).should be_true
90
+ it 'should have the replicated attribute as true' do
91
+ expect(proxy.replicated).to be true
112
92
  end
113
93
 
114
- it "should initialize the list of shards" do
115
- proxy.instance_variable_get(:@slaves_list).should == ["slave1", "slave2", "slave3", "slave4"]
94
+ it 'should initialize the list of shards' do
95
+ expect(proxy.slaves_list).to eq(%w(slave1 slave2 slave3 slave4))
116
96
  end
117
97
  end
118
98
 
119
- describe "when you have a rails application" do
99
+ describe 'when you have a rails application' do
120
100
  before(:each) do
121
- Rails = double()
122
- OctopusHelper.set_octopus_env("octopus_rails")
101
+ Rails = double
102
+ OctopusHelper.octopus_env = 'octopus_rails'
123
103
  end
124
104
 
125
105
  after(:each) do
126
106
  Object.send(:remove_const, :Rails)
127
107
  Octopus.instance_variable_set(:@config, nil)
128
108
  Octopus.instance_variable_set(:@rails_env, nil)
129
- OctopusHelper.clean_connection_proxy()
109
+ OctopusHelper.clean_connection_proxy
130
110
  end
131
111
 
132
- it "should initialize correctly octopus common variables for the environments" do
133
- Rails.stub(:env).and_return('staging')
112
+ it 'should initialize correctly octopus common variables for the environments' do
113
+ allow(Rails).to receive(:env).and_return('staging')
134
114
  Octopus.instance_variable_set(:@rails_env, nil)
135
115
  Octopus.instance_variable_set(:@environments, nil)
136
- Octopus.config()
116
+ Octopus.config
137
117
 
138
- proxy.instance_variable_get(:@replicated).should be_true
139
- Octopus.environments.should == ["staging", "production"]
118
+ expect(proxy.replicated).to be true
119
+ expect(Octopus.environments).to eq(%w(staging production))
140
120
  end
141
121
 
142
- it "should initialize correctly the shards for the staging environment" do
143
- Rails.stub(:env).and_return('staging')
122
+ it 'should initialize correctly the shards for the staging environment' do
123
+ allow(Rails).to receive(:env).and_return('staging')
144
124
  Octopus.instance_variable_set(:@rails_env, nil)
145
125
  Octopus.instance_variable_set(:@environments, nil)
146
- Octopus.config()
126
+ Octopus.config
147
127
 
148
- proxy.instance_variable_get(:@shards).keys.to_set.should == Set.new(["slave1", "slave2", "master"])
128
+ expect(proxy.shards.keys.to_set).to eq(Set.new(%w(slave1 slave2 master)))
149
129
  end
150
130
 
151
- it "should initialize correctly the shard octopus_shard value for logging" do
152
- Rails.stub(:env).and_return('staging')
131
+ it 'should initialize correctly the shard octopus_shard value for logging' do
132
+ allow(Rails).to receive(:env).and_return('staging')
153
133
  Octopus.instance_variable_set(:@rails_env, nil)
154
134
  Octopus.instance_variable_set(:@environments, nil)
155
- Octopus.config()
135
+ Octopus.config
156
136
 
157
- proxy.instance_variable_get(:@shards)['slave1'].spec.config.should have_key :octopus_shard
137
+ expect(proxy.shards['slave1'].spec.config).to have_key :octopus_shard
158
138
  end
159
139
 
160
- it "should initialize correctly the shards for the production environment" do
161
- Rails.stub(:env).and_return('production')
140
+ it 'should initialize correctly the shards for the production environment' do
141
+ allow(Rails).to receive(:env).and_return('production')
162
142
  Octopus.instance_variable_set(:@rails_env, nil)
163
143
  Octopus.instance_variable_set(:@environments, nil)
164
- Octopus.config()
144
+ Octopus.config
165
145
 
166
- proxy.instance_variable_get(:@shards).keys.to_set.should == Set.new(["slave3", "slave4", "master"])
146
+ expect(proxy.shards.keys.to_set).to eq(Set.new(%w(slave3 slave4 master)))
167
147
  end
168
148
 
169
- describe "using the master connection", :shards => [:russia, :master] do
149
+ describe 'using the master connection', :shards => [:russia, :master] do
170
150
  before(:each) do
171
- Rails.stub(:env).and_return('development')
151
+ allow(Rails).to receive(:env).and_return('development')
172
152
  end
173
153
 
174
- it "should use the master connection" do
175
- user = User.create!(:name =>"Thiago")
176
- user.name = "New Thiago"
177
- user.save()
178
- User.find_by_name("New Thiago").should_not be_nil
154
+ it 'should use the master connection' do
155
+ user = User.create!(:name => 'Thiago')
156
+ user.name = 'New Thiago'
157
+ user.save
158
+ expect(User.find_by_name('New Thiago')).not_to be_nil
179
159
  end
180
160
 
181
- it "should work when using using syntax" do
182
- user = User.using(:russia).create!(:name =>"Thiago")
161
+ it 'should work when using using syntax' do
162
+ user = User.using(:russia).create!(:name => 'Thiago')
183
163
 
184
- user.name = "New Thiago"
185
- user.save()
164
+ user.name = 'New Thiago'
165
+ user.save
186
166
 
187
- User.using(:russia).find_by_name("New Thiago").should == user
188
- User.find_by_name("New Thiago").should == user
167
+ expect(User.using(:russia).find_by_name('New Thiago')).to eq(user)
168
+ expect(User.find_by_name('New Thiago')).to eq(user)
189
169
  end
190
170
 
191
- it "should work when using blocks" do
171
+ it 'should work when using blocks' do
192
172
  Octopus.using(:russia) do
193
- @user = User.create!(:name =>"Thiago")
173
+ @user = User.create!(:name => 'Thiago')
194
174
  end
195
175
 
196
- User.find_by_name("Thiago").should == @user
176
+ expect(User.find_by_name('Thiago')).to eq(@user)
197
177
  end
198
178
 
199
- it "should work with associations" do
200
- u = Client.create!(:name => "Thiago")
201
- i = Item.create(:name => "Item")
179
+ it 'should work with associations' do
180
+ u = Client.create!(:name => 'Thiago')
181
+ i = Item.create(:name => 'Item')
202
182
  u.items << i
203
- u.save()
183
+ u.save
204
184
  end
205
185
  end
206
186
  end
207
187
 
208
- describe "returning the correct connection" do
209
- describe "should return the shard name" do
210
- it "when current_shard is empty" do
211
- proxy.shard_name.should == :master
188
+ describe 'returning the correct connection' do
189
+ describe 'should return the shard name' do
190
+ it 'when current_shard is empty' do
191
+ expect(proxy.shard_name).to eq(:master)
212
192
  end
213
193
 
214
- it "when current_shard is a single shard" do
194
+ it 'when current_shard is empty with custom master' do
195
+ OctopusHelper.using_environment :octopus do
196
+ Octopus.config[:master_shard] = :brazil
197
+ expect(proxy.shard_name).to eq(:brazil)
198
+ Octopus.config[:master_shard] = nil
199
+ end
200
+ end
201
+
202
+ it 'when current_shard is a single shard' do
215
203
  proxy.current_shard = :canada
216
- proxy.shard_name.should == :canada
204
+ expect(proxy.shard_name).to eq(:canada)
217
205
  end
218
206
 
219
- it "when current_shard is more than one shard" do
207
+ it 'when current_shard is more than one shard' do
220
208
  proxy.current_shard = [:russia, :brazil]
221
- proxy.shard_name.should == :russia
209
+ expect(proxy.shard_name).to eq(:russia)
222
210
  end
223
211
  end
224
212
 
225
- describe "should return the connection based on shard_name" do
226
- it "when current_shard is empty" do
227
- proxy.select_connection().should == proxy.instance_variable_get(:@shards)[:master].connection()
213
+ describe 'should return the connection based on shard_name' do
214
+ it 'when current_shard is empty' do
215
+ expect(proxy.select_connection).to eq(proxy.shards[:master].connection)
228
216
  end
229
217
 
230
- it "when current_shard is a single shard" do
218
+ it 'when current_shard is a single shard' do
231
219
  proxy.current_shard = :canada
232
- proxy.select_connection().should == proxy.instance_variable_get(:@shards)[:canada].connection()
220
+ expect(proxy.select_connection).to eq(proxy.shards[:canada].connection)
233
221
  end
234
222
  end
235
223
  end
236
224
 
237
- describe "saving multiple sharded objects at once" do
225
+ describe 'saving multiple sharded objects at once' do
238
226
  before :each do
239
227
  @p = MmorpgPlayer.using(:alone_shard).create!(:player_name => 'Thiago')
240
228
  end
241
229
 
242
230
  subject { @p.save! }
243
231
 
244
- context "when the objects are created with #new and saved one at a time" do
232
+ context 'when the objects are created with #new and saved one at a time' do
245
233
  before :each do
246
234
  @p.weapons.create!(:name => 'battleaxe', :hand => 'right')
247
235
  @p.skills.create!(:name => 'smiting', :weapon => @p.weapons[0])
248
236
  end
249
237
 
250
- it "should save all associated objects on the correct shard" do
238
+ it 'should save all associated objects on the correct shard' do
251
239
  expect { subject }.to_not raise_error
252
240
  end
253
241
  end
254
242
 
255
- context "when the objects are created with #new and saved at the same time" do
243
+ context 'when the objects are created with #new and saved at the same time' do
256
244
  before :each do
257
245
  @p.weapons.new(:name => 'battleaxe', :hand => 'right')
258
246
  @p.skills.new(:name => 'smiting', :weapon => @p.weapons[0])
259
247
  end
260
248
 
261
- it "should save all associated objects on the correct shard" do
249
+ it 'should save all associated objects on the correct shard' do
262
250
  expect { subject }.to_not raise_error
263
251
  end
264
252
  end
265
253
  end
266
254
 
267
- describe "connection reuse" do
255
+
256
+ describe 'cleaning the connection proxy' do
257
+ it 'should not clean #current_shard from proxy when using a block and calling #execute' do
258
+ Octopus.using(:canada) do
259
+ expect(User.connection.current_shard).to eq(:canada)
260
+
261
+ connection = User.connection
262
+
263
+ result = connection.execute('select * from users limit 1;')
264
+ result = connection.execute('select * from users limit 1;')
265
+
266
+ expect(User.connection.current_shard).to eq(:canada)
267
+ end
268
+ end
269
+ end
270
+
271
+ describe 'connection reuse' do
268
272
  before :each do
269
- @item_brazil_conn = Item.using(:brazil).new(:name => 'Brazil Item').connection.select_connection
270
- @item_canada_conn = Item.using(:canada).new(:name => 'Canada Item').connection.select_connection
273
+ @item_brazil_conn = Item.using(:brazil).new(:name => 'Brazil Item').class.connection.select_connection
274
+ @item_canada_conn = Item.using(:canada).new(:name => 'Canada Item').class.connection.select_connection
271
275
  end
272
276
 
273
- it "reuses connections" do
274
- Item.using(:brazil).new(:name => 'Another Brazil Item').connection.select_connection.should eq(@item_brazil_conn)
275
- Item.using(:canada).new(:name => 'Another Canada Item').connection.select_connection.should eq(@item_canada_conn)
277
+ it 'reuses connections' do
278
+ expect(Item.using(:brazil).new(:name => 'Another Brazil Item').class.connection.select_connection).to eq(@item_brazil_conn)
279
+ expect(Item.using(:canada).new(:name => 'Another Canada Item').class.connection.select_connection).to eq(@item_canada_conn)
276
280
  end
277
281
 
278
- it "reuses connections after clear_active_connections! is called" do
279
- Item.using(:brazil).new(:name => 'Another Brazil Item').connection.select_connection.should eq(@item_brazil_conn)
280
- Item.using(:canada).new(:name => 'Another Canada Item').connection.select_connection.should eq(@item_canada_conn)
282
+ it 'reuses connections after clear_active_connections! is called' do
283
+ expect(Item.using(:brazil).new(:name => 'Another Brazil Item').class.connection.select_connection).to eq(@item_brazil_conn)
284
+ expect(Item.using(:canada).new(:name => 'Another Canada Item').class.connection.select_connection).to eq(@item_canada_conn)
281
285
  end
282
286
 
283
- it "creates new connections after clear_all_connections! is called" do
287
+ it 'creates new connections after clear_all_connections! is called' do
284
288
  Item.clear_all_connections!
285
- Item.using(:brazil).new(:name => 'Another Brazil Item').connection.select_connection.should_not eq(@item_brazil_conn)
286
- Item.using(:canada).new(:name => 'Another Canada Item').connection.select_connection.should_not eq(@item_canada_conn)
289
+ expect(Item.using(:brazil).new(:name => 'Another Brazil Item').class.connection.select_connection).not_to eq(@item_brazil_conn)
290
+ expect(Item.using(:canada).new(:name => 'Another Canada Item').class.connection.select_connection).not_to eq(@item_canada_conn)
287
291
  end
288
292
 
289
- it "is consistent with connected?" do
290
- Item.connected?.should be_true
291
- ActiveRecord::Base.connected?.should be_true
293
+ it 'is consistent with connected?' do
294
+ expect(Item.connected?).to be true
295
+ expect(ActiveRecord::Base.connected?).to be true
292
296
 
293
297
  Item.clear_all_connections!
294
298
 
295
- Item.connected?.should be_false
296
- ActiveRecord::Base.connected?.should be_false
299
+ expect(Item.connected?).to be false
300
+ expect(ActiveRecord::Base.connected?).to be false
297
301
  end
298
302
  end
299
303
  end
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ unless Octopus.rails4? || Octopus.rails50?
4
+ describe Octopus::ConnectionPool::QueryCacheForShards do
5
+ subject(:query_cache_on_shard) { ActiveRecord::Base.using(:brazil).connection.query_cache_enabled }
6
+
7
+ context 'Octopus enabled' do
8
+ context 'when query cache is enabled on the primary connection_pool' do
9
+ before { ActiveRecord::Base.connection_pool.enable_query_cache! }
10
+ it { is_expected.to be true }
11
+ end
12
+
13
+ context 'when query cache is disabled on the primary connection_pool' do
14
+ before { ActiveRecord::Base.connection_pool.disable_query_cache! }
15
+ it { is_expected.to be false }
16
+ end
17
+ end
18
+
19
+ context 'Octopus disabled' do
20
+ before do
21
+ Rails = double
22
+ allow(Rails).to receive(:env).and_return('staging')
23
+ end
24
+
25
+ after do
26
+ Object.send(:remove_const, :Rails)
27
+ end
28
+
29
+ context 'when query cache is enabled on the primary connection_pool' do
30
+ before { ActiveRecord::Base.connection_pool.enable_query_cache! }
31
+ it { is_expected.to be true }
32
+ end
33
+
34
+ context 'when query cache is disabled on the primary connection_pool' do
35
+ before { ActiveRecord::Base.connection_pool.disable_query_cache! }
36
+ it { is_expected.to be false }
37
+ end
38
+ end
39
+ end
40
+ end