ar-octopus 0.9.2 → 0.10.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/.travis.yml +1 -8
- data/Appraisals +4 -8
- data/README.mkdn +6 -1
- data/Rakefile +1 -0
- data/ar-octopus.gemspec +4 -4
- data/gemfiles/rails42.gemfile +2 -2
- data/gemfiles/rails5.gemfile +1 -1
- data/gemfiles/rails51.gemfile +1 -1
- data/gemfiles/{rails4.gemfile → rails52.gemfile} +2 -2
- data/lib/octopus.rb +13 -13
- data/lib/octopus/association_shard_tracking.rb +1 -1
- data/lib/octopus/collection_association.rb +1 -1
- data/lib/octopus/migration.rb +102 -61
- data/lib/octopus/model.rb +8 -12
- data/lib/octopus/proxy.rb +32 -11
- data/lib/octopus/proxy_config.rb +7 -8
- data/lib/octopus/query_cache_for_shards.rb +24 -0
- data/lib/octopus/relation_proxy.rb +10 -1
- data/lib/octopus/scope_proxy.rb +1 -1
- data/lib/octopus/version.rb +1 -1
- data/spec/octopus/association_shard_tracking_spec.rb +314 -0
- data/spec/octopus/migration_spec.rb +29 -14
- data/spec/octopus/model_spec.rb +20 -3
- data/spec/octopus/proxy_spec.rb +1 -1
- data/spec/octopus/query_cache_for_shards_spec.rb +40 -0
- data/spec/octopus/replication_spec.rb +57 -2
- data/spec/octopus/scope_proxy_spec.rb +21 -0
- data/spec/support/octopus_helper.rb +13 -4
- metadata +19 -12
- data/gemfiles/rails41.gemfile +0 -7
- data/lib/octopus/has_and_belongs_to_many_association.rb +0 -9
data/spec/octopus/model_spec.rb
CHANGED
@@ -306,8 +306,13 @@ describe Octopus::Model do
|
|
306
306
|
|
307
307
|
describe 'using a postgresql shard' do
|
308
308
|
it 'should update the Arel Engine' do
|
309
|
-
|
310
|
-
|
309
|
+
if Octopus.atleast_rails52?
|
310
|
+
expect(User.using(:postgresql_shard).connection.adapter_name).to eq('PostgreSQL')
|
311
|
+
expect(User.using(:alone_shard).connection.adapter_name).to eq('Mysql2')
|
312
|
+
else
|
313
|
+
expect(User.using(:postgresql_shard).arel_engine.connection.adapter_name).to eq('PostgreSQL')
|
314
|
+
expect(User.using(:alone_shard).arel_engine.connection.adapter_name).to eq('Mysql2')
|
315
|
+
end
|
311
316
|
end
|
312
317
|
|
313
318
|
it 'should works with writes and reads' do
|
@@ -393,6 +398,18 @@ describe Octopus::Model do
|
|
393
398
|
expect(User.using(:master).maximum(:number)).to eq(12)
|
394
399
|
end
|
395
400
|
|
401
|
+
it 'sum' do
|
402
|
+
u = User.using(:brazil).create!(:name => 'Teste', :number => 11)
|
403
|
+
v = User.using(:master).create!(:name => 'Teste', :number => 12)
|
404
|
+
|
405
|
+
expect(User.using(:master).sum(:number)).to eq(12)
|
406
|
+
expect(User.using(:brazil).sum(:number)).to eq(11)
|
407
|
+
|
408
|
+
expect(User.where(id: v.id).sum(:number)).to eq(12)
|
409
|
+
expect(User.using(:brazil).where(id: u.id).sum(:number)).to eq(11)
|
410
|
+
expect(User.using(:master).where(id: v.id).sum(:number)).to eq(12)
|
411
|
+
end
|
412
|
+
|
396
413
|
describe 'any?' do
|
397
414
|
before { User.using(:brazil).create!(:name => 'User1') }
|
398
415
|
|
@@ -747,7 +764,7 @@ describe Octopus::Model do
|
|
747
764
|
|
748
765
|
replicated_cat = User.find_by_name 'Thiago'
|
749
766
|
|
750
|
-
expect(replicated_cat.current_shard.to_s).to match(/
|
767
|
+
expect(replicated_cat.current_shard.to_s).to match(/master/)
|
751
768
|
end
|
752
769
|
end
|
753
770
|
end
|
data/spec/octopus/proxy_spec.rb
CHANGED
@@ -33,7 +33,7 @@ describe Octopus::Proxy do
|
|
33
33
|
expect(config[:username]).to eq("#{ENV['MYSQL_USER'] || 'root'}")
|
34
34
|
end
|
35
35
|
|
36
|
-
unless Octopus.rails50? || Octopus.rails51?
|
36
|
+
unless Octopus.rails50? || Octopus.rails51?|| Octopus.rails52?
|
37
37
|
it 'should respond correctly to respond_to?(:pk_and_sequence_for)' do
|
38
38
|
expect(proxy.respond_to?(:pk_and_sequence_for)).to be true
|
39
39
|
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
|
@@ -1,6 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe 'when the database is replicated' do
|
4
|
+
let(:slave_pool) do
|
5
|
+
ActiveRecord::Base.connection_proxy.shards['slave1']
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:slave_connection) do
|
9
|
+
slave_pool.connection
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:master_pool) do
|
13
|
+
ActiveRecord::Base.connection_proxy.shards['master']
|
14
|
+
end
|
15
|
+
|
16
|
+
let(:master_connection) do
|
17
|
+
master_pool.connection
|
18
|
+
end
|
19
|
+
|
4
20
|
it 'should send all writes/reads queries to master when you have a non replicated model' do
|
5
21
|
OctopusHelper.using_environment :production_replicated do
|
6
22
|
u = User.create!(:name => 'Replicated')
|
@@ -26,10 +42,49 @@ describe 'when the database is replicated' do
|
|
26
42
|
end
|
27
43
|
end
|
28
44
|
|
45
|
+
context 'when updating model' do
|
46
|
+
it 'should send writes to master' do
|
47
|
+
OctopusHelper.using_environment :replicated_with_one_slave do
|
48
|
+
Cat.using(:slave1).create!(:name => 'Cat')
|
49
|
+
cat = Cat.find_by_name('Cat')
|
50
|
+
cat.name = 'New name'
|
51
|
+
|
52
|
+
expect(master_connection).to receive(:update).and_call_original
|
53
|
+
|
54
|
+
cat.save!
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when querying' do
|
60
|
+
it 'Reads from slave' do
|
61
|
+
OctopusHelper.using_environment :replicated_with_one_slave do
|
62
|
+
expect(master_connection).not_to receive(:select)
|
63
|
+
|
64
|
+
Cat.where(:name => 'Catman2').first
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context 'When record is read from slave' do
|
70
|
+
it 'Should write associations to master' do
|
71
|
+
OctopusHelper.using_environment :replicated_with_one_slave do
|
72
|
+
client = Client.using(:slave1).create!(:name => 'Client')
|
73
|
+
|
74
|
+
client = Client.find(client.id)
|
75
|
+
|
76
|
+
expect(master_connection).to receive(:insert).and_call_original
|
77
|
+
|
78
|
+
client.items.create!(:name => 'Item')
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
29
84
|
describe 'When enabling the query cache' do
|
30
85
|
include_context 'with query cache enabled' do
|
31
86
|
it 'should do the queries with cache' do
|
32
|
-
OctopusHelper.using_environment :replicated_with_one_slave
|
87
|
+
OctopusHelper.using_environment :replicated_with_one_slave do
|
33
88
|
cat1 = Cat.using(:master).create!(:name => 'Master Cat 1')
|
34
89
|
_ct2 = Cat.using(:master).create!(:name => 'Master Cat 2')
|
35
90
|
expect(Cat.using(:master).find(cat1.id)).to eq(cat1)
|
@@ -44,7 +99,7 @@ describe 'when the database is replicated' do
|
|
44
99
|
|
45
100
|
# Rails 5.1 count the cached queries as regular queries.
|
46
101
|
# TODO: How we can verify if the queries are using cache on Rails 5.1? - @thiagopradi
|
47
|
-
expected_records = Octopus.rails51? ? 19 : 14
|
102
|
+
expected_records = Octopus.rails51? || Octopus.rails52? ? 19 : 14
|
48
103
|
|
49
104
|
expect(counter.query_count).to eq(expected_records)
|
50
105
|
end
|
@@ -73,4 +73,25 @@ describe Octopus::ScopeProxy do
|
|
73
73
|
expect(cloned_object.object_id).not_to eq(user.object_id)
|
74
74
|
end
|
75
75
|
end
|
76
|
+
|
77
|
+
context 'When iterated with Enumerable methods' do
|
78
|
+
before(:each) do
|
79
|
+
User.using(:brazil).create!(:name => 'Evan', :number => 1)
|
80
|
+
User.using(:brazil).create!(:name => 'Evan', :number => 2)
|
81
|
+
User.using(:brazil).create!(:name => 'Evan', :number => 3)
|
82
|
+
@evans = User.using(:brazil).where(:name => 'Evan')
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'allows each method' do
|
86
|
+
expect(@evans.each.count).to eq(3)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'allows each_with_index method' do
|
90
|
+
expect(@evans.each_with_index.to_a.flatten.count).to eq(6)
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'allows map method' do
|
94
|
+
expect(@evans.map(&:number)).to eq([1, 2, 3])
|
95
|
+
end
|
96
|
+
end
|
76
97
|
end
|
@@ -8,12 +8,12 @@ module OctopusHelper
|
|
8
8
|
%w(schema_migrations users clients cats items keyboards computers permissions_roles roles permissions assignments projects programmers yummy adverts).each do |tables|
|
9
9
|
BlankModel.using(shard_symbol).connection.execute("DELETE FROM #{tables}")
|
10
10
|
end
|
11
|
-
|
12
11
|
if shard_symbol == 'alone_shard'
|
13
12
|
%w(mmorpg_players weapons skills).each do |table|
|
14
13
|
BlankModel.using(shard_symbol).connection.execute("DELETE FROM #{table}")
|
15
14
|
end
|
16
15
|
end
|
16
|
+
BlankModel.using(:master).connection.shards[shard_symbol].disconnect if Octopus.atleast_rails50?
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -29,12 +29,21 @@ module OctopusHelper
|
|
29
29
|
|
30
30
|
def self.migrating_to_version(version, &_block)
|
31
31
|
migrations_root = File.expand_path(File.join(File.dirname(__FILE__), '..', 'migrations'))
|
32
|
-
|
32
|
+
|
33
33
|
begin
|
34
|
-
|
34
|
+
migrate_to_version(:up, migrations_root, version)
|
35
35
|
yield
|
36
36
|
ensure
|
37
|
-
|
37
|
+
migrate_to_version(:down, migrations_root, version)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.migrate_to_version(direction, root, version)
|
42
|
+
if Octopus.atleast_rails52?
|
43
|
+
migrations = ActiveRecord::MigrationContext.new(root).migrations.select {|mig| version == mig.version }
|
44
|
+
ActiveRecord::Migrator.new(direction, migrations, version).run
|
45
|
+
else
|
46
|
+
ActiveRecord::Migrator.run(direction, root, version)
|
38
47
|
end
|
39
48
|
end
|
40
49
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ar-octopus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.10.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Thiago Pradi
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2018-
|
13
|
+
date: 2018-10-31 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: activerecord
|
@@ -18,28 +18,28 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - ">="
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 4.
|
21
|
+
version: 4.2.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - ">="
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 4.
|
28
|
+
version: 4.2.0
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
30
|
name: activesupport
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
33
|
- - ">="
|
34
34
|
- !ruby/object:Gem::Version
|
35
|
-
version: 4.
|
35
|
+
version: 4.2.0
|
36
36
|
type: :runtime
|
37
37
|
prerelease: false
|
38
38
|
version_requirements: !ruby/object:Gem::Requirement
|
39
39
|
requirements:
|
40
40
|
- - ">="
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: 4.
|
42
|
+
version: 4.2.0
|
43
43
|
- !ruby/object:Gem::Dependency
|
44
44
|
name: appraisal
|
45
45
|
requirement: !ruby/object:Gem::Requirement
|
@@ -58,16 +58,22 @@ dependencies:
|
|
58
58
|
name: mysql2
|
59
59
|
requirement: !ruby/object:Gem::Requirement
|
60
60
|
requirements:
|
61
|
-
- - "
|
61
|
+
- - ">="
|
62
62
|
- !ruby/object:Gem::Version
|
63
63
|
version: 0.3.18
|
64
|
+
- - "<"
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0.5'
|
64
67
|
type: :development
|
65
68
|
prerelease: false
|
66
69
|
version_requirements: !ruby/object:Gem::Requirement
|
67
70
|
requirements:
|
68
|
-
- - "
|
71
|
+
- - ">="
|
69
72
|
- !ruby/object:Gem::Version
|
70
73
|
version: 0.3.18
|
74
|
+
- - "<"
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0.5'
|
71
77
|
- !ruby/object:Gem::Dependency
|
72
78
|
name: pg
|
73
79
|
requirement: !ruby/object:Gem::Requirement
|
@@ -174,11 +180,10 @@ files:
|
|
174
180
|
- Rakefile
|
175
181
|
- TODO.txt
|
176
182
|
- ar-octopus.gemspec
|
177
|
-
- gemfiles/rails4.gemfile
|
178
|
-
- gemfiles/rails41.gemfile
|
179
183
|
- gemfiles/rails42.gemfile
|
180
184
|
- gemfiles/rails5.gemfile
|
181
185
|
- gemfiles/rails51.gemfile
|
186
|
+
- gemfiles/rails52.gemfile
|
182
187
|
- lib/ar-octopus.rb
|
183
188
|
- lib/octopus.rb
|
184
189
|
- lib/octopus/abstract_adapter.rb
|
@@ -188,7 +193,6 @@ files:
|
|
188
193
|
- lib/octopus/collection_proxy.rb
|
189
194
|
- lib/octopus/exception.rb
|
190
195
|
- lib/octopus/finder_methods.rb
|
191
|
-
- lib/octopus/has_and_belongs_to_many_association.rb
|
192
196
|
- lib/octopus/load_balancing.rb
|
193
197
|
- lib/octopus/load_balancing/round_robin.rb
|
194
198
|
- lib/octopus/log_subscriber.rb
|
@@ -197,6 +201,7 @@ files:
|
|
197
201
|
- lib/octopus/persistence.rb
|
198
202
|
- lib/octopus/proxy.rb
|
199
203
|
- lib/octopus/proxy_config.rb
|
204
|
+
- lib/octopus/query_cache_for_shards.rb
|
200
205
|
- lib/octopus/railtie.rb
|
201
206
|
- lib/octopus/relation_proxy.rb
|
202
207
|
- lib/octopus/result_patch.rb
|
@@ -307,6 +312,7 @@ files:
|
|
307
312
|
- spec/octopus/model_spec.rb
|
308
313
|
- spec/octopus/octopus_spec.rb
|
309
314
|
- spec/octopus/proxy_spec.rb
|
315
|
+
- spec/octopus/query_cache_for_shards_spec.rb
|
310
316
|
- spec/octopus/relation_proxy_spec.rb
|
311
317
|
- spec/octopus/replicated_slave_grouped_spec.rb
|
312
318
|
- spec/octopus/replication_spec.rb
|
@@ -337,7 +343,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
337
343
|
requirements:
|
338
344
|
- - ">="
|
339
345
|
- !ruby/object:Gem::Version
|
340
|
-
version: 2.
|
346
|
+
version: 2.2.0
|
341
347
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
342
348
|
requirements:
|
343
349
|
- - ">="
|
@@ -374,6 +380,7 @@ test_files:
|
|
374
380
|
- spec/octopus/model_spec.rb
|
375
381
|
- spec/octopus/octopus_spec.rb
|
376
382
|
- spec/octopus/proxy_spec.rb
|
383
|
+
- spec/octopus/query_cache_for_shards_spec.rb
|
377
384
|
- spec/octopus/relation_proxy_spec.rb
|
378
385
|
- spec/octopus/replicated_slave_grouped_spec.rb
|
379
386
|
- spec/octopus/replication_spec.rb
|
data/gemfiles/rails41.gemfile
DELETED