ar-multidb 0.5.1 → 0.7.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.
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ RSpec.describe Multidb do
6
+ let(:balancer) { instance_double('Multidb::Balancer', use: nil, get: nil, disconnect!: nil) }
7
+
8
+ describe '.balancer' do
9
+ subject { described_class.balancer }
10
+
11
+ context 'with no configuration' do
12
+ it 'raises exception' do
13
+ expect { subject }.to raise_error(Multidb::NotInitializedError)
14
+ end
15
+ end
16
+
17
+ context 'with configuration' do
18
+ before do
19
+ ActiveRecord::Base.establish_connection(configuration_with_replicas)
20
+ end
21
+
22
+ it 'returns balancer' do
23
+ is_expected.to be_an_instance_of(Multidb::Balancer)
24
+ end
25
+ end
26
+ end
27
+
28
+ describe '.init' do
29
+ subject { described_class.init(config) }
30
+
31
+ let(:config) { configuration_with_replicas }
32
+
33
+ it 'initializes @balancer' do
34
+ expect { subject }.to change {
35
+ described_class.instance_variable_get(:@balancer)
36
+ }.from(nil).to an_instance_of(Multidb::Balancer)
37
+ end
38
+
39
+ it 'initializes the balancer with a configuration object' do
40
+ allow(Multidb::Configuration).to receive(:new)
41
+
42
+ subject
43
+
44
+ expect(Multidb::Configuration).to have_received(:new).with(config.except('multidb'), config['multidb'])
45
+ end
46
+ end
47
+
48
+ describe '.reset!' do
49
+ subject { described_class.reset! }
50
+
51
+ before do
52
+ described_class.instance_variable_set(:@balancer, balancer)
53
+ end
54
+
55
+ it 'clears @balancer' do
56
+ expect { subject }.to change {
57
+ described_class.instance_variable_get(:@balancer)
58
+ }.from(balancer).to(nil)
59
+ end
60
+
61
+ it 'clears the multidb thread local' do
62
+ Thread.current[:multidb] = { some: :value }
63
+
64
+ expect { subject }.to change { Thread.current[:multidb] }.to nil
65
+ end
66
+ end
67
+
68
+ describe 'balancer delegates' do
69
+ before do
70
+ described_class.instance_variable_set(:@balancer, balancer)
71
+ end
72
+
73
+ it 'delegates use to the balancer' do
74
+ described_class.use(:name)
75
+
76
+ expect(balancer).to have_received(:use).with(:name)
77
+ end
78
+
79
+ it 'delegates get to the balancer' do
80
+ described_class.get(:name)
81
+
82
+ expect(balancer).to have_received(:get).with(:name)
83
+ end
84
+
85
+ it 'delegates disconnect! to the balancer' do
86
+ described_class.disconnect!
87
+
88
+ expect(balancer).to have_received(:disconnect!)
89
+ end
90
+ end
91
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,5 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+
3
6
  ENV['RACK_ENV'] ||= 'test'
4
7
 
5
8
  require 'rspec'
@@ -10,16 +13,38 @@ require 'fileutils'
10
13
  $LOAD_PATH.unshift(File.expand_path('lib', __dir__))
11
14
  require 'multidb'
12
15
 
13
- require_relative 'helpers'
16
+ Dir[File.join(__dir__, 'support', '**', '*.rb')].sort.each { |f| require f }
14
17
 
15
18
  RSpec.configure do |config|
16
- config.include Helpers
17
- config.expect_with(:rspec) { |c| c.syntax = :should }
18
- config.before :each do
19
+ config.disable_monkey_patching!
20
+ config.order = :random
21
+ Kernel.srand config.seed
22
+
23
+ config.filter_run :focus
24
+ config.run_all_when_everything_filtered = true
25
+
26
+ config.filter_run_excluding rails: lambda { |v|
27
+ rails_version = Gem::Version.new(ActiveRecord::VERSION::STRING)
28
+ test = Gem::Requirement.new(v)
29
+ !test.satisfied_by?(rails_version)
30
+ }
31
+
32
+ config.expect_with :rspec do |expectations|
33
+ expectations.syntax = :expect
34
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
35
+ end
36
+
37
+ config.mock_with :rspec do |mocks|
38
+ mocks.verify_partial_doubles = true
39
+ end
40
+
41
+ config.before do
19
42
  ActiveRecord::Base.clear_all_connections!
20
43
  Multidb.reset!
21
44
  end
22
- config.after :each do
45
+
46
+ config.after do
47
+ Multidb.reset!
23
48
  Dir.glob(File.expand_path('test*.sqlite', __dir__)).each do |f|
24
49
  FileUtils.rm(f)
25
50
  end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec::Matchers.define :have_database do |expected|
4
+ match do |conn|
5
+ list = conn.execute('pragma database_list')
6
+ @result = File.basename(list.first&.[]('file'))
7
+ @result == expected
8
+ end
9
+ description do
10
+ "be connected to #{expected}"
11
+ end
12
+ failure_message do |actual|
13
+ "expected that #{actual} would be connected to #{expected}, found #{@result}"
14
+ end
15
+ end
@@ -16,8 +16,11 @@ module Helpers
16
16
  - database: spec/test-replica3-1.sqlite
17
17
  - database: spec/test-replica3-2.sqlite
18
18
  replica_alias:
19
- database: spec/test-replica2.sqlite
20
19
  alias: replica2
21
20
  YAML
22
21
  end
23
22
  end
23
+
24
+ RSpec.configure do |config|
25
+ config.include Helpers
26
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ar-multidb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Staubo
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-10-18 00:00:00.000000000 Z
12
+ date: 2024-02-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -20,7 +20,7 @@ dependencies:
20
20
  version: '5.1'
21
21
  - - "<"
22
22
  - !ruby/object:Gem::Version
23
- version: '6.1'
23
+ version: '7.2'
24
24
  type: :runtime
25
25
  prerelease: false
26
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -30,7 +30,7 @@ dependencies:
30
30
  version: '5.1'
31
31
  - - "<"
32
32
  - !ruby/object:Gem::Version
33
- version: '6.1'
33
+ version: '7.2'
34
34
  - !ruby/object:Gem::Dependency
35
35
  name: activesupport
36
36
  requirement: !ruby/object:Gem::Requirement
@@ -40,7 +40,7 @@ dependencies:
40
40
  version: '5.1'
41
41
  - - "<"
42
42
  - !ruby/object:Gem::Version
43
- version: '6.1'
43
+ version: '7.2'
44
44
  type: :runtime
45
45
  prerelease: false
46
46
  version_requirements: !ruby/object:Gem::Requirement
@@ -50,21 +50,21 @@ dependencies:
50
50
  version: '5.1'
51
51
  - - "<"
52
52
  - !ruby/object:Gem::Version
53
- version: '6.1'
53
+ version: '7.2'
54
54
  - !ruby/object:Gem::Dependency
55
55
  name: rake
56
56
  requirement: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '12.0'
60
+ version: '13.0'
61
61
  type: :development
62
62
  prerelease: false
63
63
  version_requirements: !ruby/object:Gem::Requirement
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: '12.0'
67
+ version: '13.0'
68
68
  - !ruby/object:Gem::Dependency
69
69
  name: rspec
70
70
  requirement: !ruby/object:Gem::Requirement
@@ -85,14 +85,56 @@ dependencies:
85
85
  requirements:
86
86
  - - "~>"
87
87
  - !ruby/object:Gem::Version
88
- version: 1.12.1
88
+ version: 1.28.0
89
89
  type: :development
90
90
  prerelease: false
91
91
  version_requirements: !ruby/object:Gem::Requirement
92
92
  requirements:
93
93
  - - "~>"
94
94
  - !ruby/object:Gem::Version
95
- version: 1.12.1
95
+ version: 1.28.0
96
+ - !ruby/object:Gem::Dependency
97
+ name: rubocop-rspec
98
+ requirement: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: 2.10.0
103
+ type: :development
104
+ prerelease: false
105
+ version_requirements: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 2.10.0
110
+ - !ruby/object:Gem::Dependency
111
+ name: simplecov
112
+ requirement: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 0.21.2
117
+ type: :development
118
+ prerelease: false
119
+ version_requirements: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - "~>"
122
+ - !ruby/object:Gem::Version
123
+ version: 0.21.2
124
+ - !ruby/object:Gem::Dependency
125
+ name: simplecov-lcov
126
+ requirement: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - "~>"
129
+ - !ruby/object:Gem::Version
130
+ version: 0.8.0
131
+ type: :development
132
+ prerelease: false
133
+ version_requirements: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - "~>"
136
+ - !ruby/object:Gem::Version
137
+ version: 0.8.0
96
138
  - !ruby/object:Gem::Dependency
97
139
  name: sqlite3
98
140
  requirement: !ruby/object:Gem::Requirement
@@ -116,18 +158,22 @@ executables: []
116
158
  extensions: []
117
159
  extra_rdoc_files: []
118
160
  files:
161
+ - ".github/workflows/prs.yml"
119
162
  - ".gitignore"
120
163
  - ".rubocop.yml"
121
- - ".travis.yml"
164
+ - ".simplecov"
122
165
  - CHANGELOG.md
123
166
  - Gemfile
124
167
  - LICENSE
125
168
  - README.markdown
126
169
  - Rakefile
127
170
  - ar-multidb.gemspec
128
- - gemfiles/activerecord51.gemfile
129
- - gemfiles/activerecord52.gemfile
130
- - gemfiles/activerecord60.gemfile
171
+ - gemfiles/activerecord-5.1.gemfile
172
+ - gemfiles/activerecord-5.2.gemfile
173
+ - gemfiles/activerecord-6.0.gemfile
174
+ - gemfiles/activerecord-6.1.gemfile
175
+ - gemfiles/activerecord-7.0.gemfile
176
+ - gemfiles/activerecord-7.1.gemfile
131
177
  - lib/ar-multidb.rb
132
178
  - lib/multidb.rb
133
179
  - lib/multidb/balancer.rb
@@ -136,13 +182,20 @@ files:
136
182
  - lib/multidb/log_subscriber.rb
137
183
  - lib/multidb/model_extensions.rb
138
184
  - lib/multidb/version.rb
139
- - spec/balancer_spec.rb
140
- - spec/helpers.rb
185
+ - spec/lib/multidb/balancer_spec.rb
186
+ - spec/lib/multidb/candidate_spec.rb
187
+ - spec/lib/multidb/configuration_spec.rb
188
+ - spec/lib/multidb/log_subscriber_extension_spec.rb
189
+ - spec/lib/multidb/model_extensions_spec.rb
190
+ - spec/lib/multidb_spec.rb
141
191
  - spec/spec_helper.rb
142
- homepage: ''
192
+ - spec/support/have_database_matcher.rb
193
+ - spec/support/helpers.rb
194
+ homepage: https://github.com/OutOfOrder/multidb
143
195
  licenses:
144
196
  - MIT
145
- metadata: {}
197
+ metadata:
198
+ rubygems_mfa_required: 'true'
146
199
  post_install_message:
147
200
  rdoc_options: []
148
201
  require_paths:
@@ -151,7 +204,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
151
204
  requirements:
152
205
  - - ">="
153
206
  - !ruby/object:Gem::Version
154
- version: 2.4.0
207
+ version: 2.5.0
155
208
  required_rubygems_version: !ruby/object:Gem::Requirement
156
209
  requirements:
157
210
  - - ">="
@@ -164,6 +217,12 @@ specification_version: 4
164
217
  summary: Multidb is an ActiveRecord extension for switching between multiple database
165
218
  connections, such as primary/replica setups.
166
219
  test_files:
167
- - spec/balancer_spec.rb
168
- - spec/helpers.rb
220
+ - spec/lib/multidb/balancer_spec.rb
221
+ - spec/lib/multidb/candidate_spec.rb
222
+ - spec/lib/multidb/configuration_spec.rb
223
+ - spec/lib/multidb/log_subscriber_extension_spec.rb
224
+ - spec/lib/multidb/model_extensions_spec.rb
225
+ - spec/lib/multidb_spec.rb
169
226
  - spec/spec_helper.rb
227
+ - spec/support/have_database_matcher.rb
228
+ - spec/support/helpers.rb
data/.travis.yml DELETED
@@ -1,17 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- cache: bundler
4
-
5
- script:
6
- - bundle exec rubocop
7
- - bundle exec rspec
8
-
9
- matrix:
10
- fast_finish: true
11
- include:
12
- - rvm: 2.5
13
- gemfile: gemfiles/activerecord51.gemfile
14
- - rvm: 2.5
15
- gemfile: gemfiles/activerecord52.gemfile
16
- - rvm: 2.5
17
- gemfile: gemfiles/activerecord60.gemfile
@@ -1,161 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative 'spec_helper'
4
-
5
- describe 'Multidb.balancer' do
6
- context 'with no configuration' do
7
- it 'raises exception' do
8
- -> { Multidb.balancer }.should raise_error(Multidb::NotInitializedError)
9
- end
10
- end
11
-
12
- context 'with configuration' do
13
- before do
14
- ActiveRecord::Base.establish_connection(configuration_with_replicas)
15
- end
16
-
17
- it 'returns balancer' do
18
- Multidb.balancer.should_not eq nil
19
- end
20
-
21
- it 'returns main connection by default' do
22
- conn = ActiveRecord::Base.connection
23
-
24
- list = conn.execute('pragma database_list')
25
- list.length.should eq 1
26
- File.basename(list[0]['file']).should eq 'test.sqlite'
27
-
28
- Multidb.balancer.current_connection.should eq conn
29
- end
30
-
31
- it 'returns default connection name for default connection' do
32
- ActiveRecord::Base.connection
33
-
34
- Multidb.balancer.current_connection_name.should eq :default
35
- end
36
-
37
- context 'with additional configurations' do
38
- before do
39
- additional_configuration = { replica4: { database: 'spec/test-replica4.sqlite' } }
40
- Multidb.balancer.append(additional_configuration)
41
- end
42
-
43
- it 'makes the new database available' do
44
- Multidb.use(:replica4) do
45
- conn = ActiveRecord::Base.connection
46
- conn.should eq Multidb.balancer.current_connection
47
- list = conn.execute('pragma database_list')
48
- list.length.should eq 1
49
- File.basename(list[0]['file']).should eq 'test-replica4.sqlite'
50
- end
51
- end
52
-
53
- it 'returns the connection name' do
54
- Multidb.use(:replica4) do
55
- Multidb.balancer.current_connection_name.should eq :replica4
56
- end
57
- end
58
- end
59
- end
60
-
61
- describe '#use' do
62
- context 'with configuration' do
63
- before do
64
- ActiveRecord::Base.establish_connection(configuration_with_replicas)
65
- end
66
-
67
- context 'undefined connection' do
68
- it 'raises exception' do
69
- lambda {
70
- Multidb.use(:something) do
71
- end
72
- }.should raise_error(ArgumentError)
73
- end
74
- end
75
-
76
- it 'returns default connection on :default' do
77
- ActiveRecord::Base.connection
78
- Multidb.use(:default) do
79
- conn2 = ActiveRecord::Base.connection
80
- conn2.should eq Multidb.balancer.current_connection
81
-
82
- list = conn2.execute('pragma database_list')
83
- list.length.should eq 1
84
- File.basename(list[0]['file']).should eq 'test.sqlite'
85
- end
86
- end
87
-
88
- it 'returns replica connection' do
89
- Multidb.use(:replica1) do
90
- conn = ActiveRecord::Base.connection
91
- conn.should eq Multidb.balancer.current_connection
92
- list = conn.execute('pragma database_list')
93
- list.length.should eq 1
94
- File.basename(list[0]['file']).should eq 'test-replica1.sqlite'
95
- end
96
- end
97
-
98
- it 'returns results instead of relation' do
99
- foobar_class = Class.new(ActiveRecord::Base) do
100
- self.table_name = 'foo_bars'
101
- end
102
- res = Multidb.use(:replica1) do
103
- ActiveRecord::Migration.verbose = false
104
- ActiveRecord::Schema.define(version: 1) { create_table :foo_bars }
105
- foobar_class.where(id: 42)
106
- end
107
- res.should eq []
108
- end
109
-
110
- it 'returns supports nested replica connection' do
111
- Multidb.use(:replica1) do
112
- Multidb.use(:replica2) do
113
- conn = ActiveRecord::Base.connection
114
- conn.should eq Multidb.balancer.current_connection
115
- list = conn.execute('pragma database_list')
116
- list.length.should eq 1
117
- File.basename(list[0]['file']).should eq 'test-replica2.sqlite'
118
- end
119
- end
120
- end
121
-
122
- it 'returns preserves state when nesting' do
123
- Multidb.use(:replica1) do
124
- Multidb.use(:replica2) do
125
- conn = ActiveRecord::Base.connection
126
- conn.should eq Multidb.balancer.current_connection
127
- list = conn.execute('pragma database_list')
128
- list.length.should eq 1
129
- File.basename(list[0]['file']).should eq 'test-replica2.sqlite'
130
- end
131
-
132
- conn = ActiveRecord::Base.connection
133
- conn.should eq Multidb.balancer.current_connection
134
- list = conn.execute('pragma database_list')
135
- list.length.should eq 1
136
- File.basename(list[0]['file']).should eq 'test-replica1.sqlite'
137
- end
138
- end
139
-
140
- it 'returns the parent connection for aliases' do
141
- Multidb.use(:replica1).should_not eq Multidb.use(:replica_alias)
142
- Multidb.use(:replica2).should eq Multidb.use(:replica_alias)
143
- end
144
-
145
- it 'returns random candidate' do
146
- names = []
147
- 100.times do
148
- Multidb.use(:replica3) do
149
- list = ActiveRecord::Base.connection.execute('pragma database_list')
150
- list.length.should eq 1
151
- names.push(File.basename(list[0]['file']))
152
- end
153
- end
154
- names.sort.uniq.should eq [
155
- 'test-replica3-1.sqlite',
156
- 'test-replica3-2.sqlite'
157
- ]
158
- end
159
- end
160
- end
161
- end