octoshark 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/Appraisals +4 -0
- data/README.md +68 -38
- data/gemfiles/rails4.2.gemfile +7 -0
- data/lib/octoshark.rb +14 -46
- data/lib/octoshark/active_record_extensions.rb +5 -1
- data/lib/octoshark/connection_manager.rb +110 -0
- data/lib/octoshark/error.rb +6 -0
- data/lib/octoshark/version.rb +1 -1
- data/spec/octoshark/active_record_extensions_spec.rb +4 -13
- data/spec/octoshark/connection_manager_spec.rb +211 -0
- data/spec/octoshark_spec.rb +21 -74
- data/spec/spec_helper.rb +0 -1
- data/spec/support/helpers.rb +0 -12
- metadata +7 -5
- data/lib/octoshark/connection_switcher.rb +0 -77
- data/spec/octoshark/connection_switcher_spec.rb +0 -167
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 055693668b801861b20b03a2b5d59cbe98a01184
|
4
|
+
data.tar.gz: 0b23a9ce02c5c88ec3c3abfae20ab9433e934221
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d2301c93076eb07afa01dead10f23c17524a5772089df8ecf5ddffca1902ff2fe3ad4022ca38db4b70a8fe6c7f8387335b6e2e2750c11cfb830a07fc14c5b9ce
|
7
|
+
data.tar.gz: 64f37f5fde130bc56398cbfc40e397f16cbd8c8a294db6638c44f0bcec799c9a7f9459ab34dbdff5d49a32f699a96e7bf13d3ae250cefd7a05dd333c2e066987
|
data/.travis.yml
CHANGED
data/Appraisals
CHANGED
data/README.md
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
![Travis status](https://travis-ci.org/dalibor/octoshark.png)
|
4
4
|
|
5
|
-
Octoshark is a simple ActiveRecord connection
|
5
|
+
Octoshark is a simple ActiveRecord connection manager. It provides a connection switching mechanism that can be used in various scenarios like: sharding, master-slave, multi-tenancy, etc. You have control over how connections are configured and used, see below for examples.
|
6
6
|
|
7
7
|
|
8
8
|
## Installation
|
@@ -28,97 +28,122 @@ $ gem install octoshark
|
|
28
28
|
|
29
29
|
## Usage
|
30
30
|
|
31
|
-
|
31
|
+
Create a new connection manager with connection 2 pools for Octoshark to manage. This usually goes in the app initializer.
|
32
32
|
|
33
33
|
```ruby
|
34
|
-
Octoshark.
|
34
|
+
CONN_MANAGER = Octoshark::ConnectionManager.new({
|
35
35
|
db1: { adapter: "sqlite3", database: "db/db1.sqlite" },
|
36
36
|
db2: { adapter: "sqlite3", database: "db/db2.sqlite" }
|
37
37
|
})
|
38
38
|
```
|
39
39
|
|
40
|
-
Configure which ActiveRecord
|
40
|
+
Configure which ActiveRecord model will use the Octoshark connection by overriding the `Model.connection` method.
|
41
41
|
|
42
42
|
```ruby
|
43
43
|
class Post < ActiveRecord::Base
|
44
44
|
def self.connection
|
45
|
-
|
45
|
+
CONN_MANAGER.current_connection
|
46
46
|
end
|
47
47
|
end
|
48
48
|
```
|
49
49
|
|
50
|
-
|
50
|
+
Alternatively, extract it as a module and include in models.
|
51
51
|
|
52
52
|
```ruby
|
53
|
-
|
54
|
-
|
55
|
-
|
53
|
+
module ShardingModel
|
54
|
+
extend ActiveSupport::Concern
|
55
|
+
|
56
|
+
module ClassMethods
|
57
|
+
def connection
|
58
|
+
OCTOSHARK.current_connection
|
59
|
+
end
|
60
|
+
end
|
56
61
|
end
|
57
62
|
```
|
58
63
|
|
59
|
-
|
64
|
+
To use a specific database connection:
|
60
65
|
|
61
|
-
|
66
|
+
```ruby
|
67
|
+
CONN_MANAGER.with_connection(:db1) do
|
68
|
+
# run queries on db1
|
69
|
+
Post.first
|
70
|
+
end
|
71
|
+
```
|
62
72
|
|
63
|
-
Multiple
|
73
|
+
Multiple `with_connection` blocks can be nested:
|
64
74
|
|
65
75
|
```ruby
|
66
|
-
|
67
|
-
#
|
76
|
+
CONN_MANAGER.with_connection(:db1) do
|
77
|
+
# run queries on db1
|
68
78
|
|
69
|
-
|
70
|
-
#
|
79
|
+
CONN_MANAGER.with_connection(:db2) do
|
80
|
+
# run queries on db2
|
71
81
|
end
|
72
82
|
|
73
|
-
#
|
83
|
+
# run queries on db1
|
74
84
|
end
|
75
85
|
```
|
76
86
|
|
87
|
+
`CONN_MANAGER.current_connection` returns the active connection while in the `with_connection` block or raises `Octoshark::Error::NoCurrentConnection` otherwise.
|
88
|
+
|
77
89
|
|
78
|
-
## Sharding
|
90
|
+
## Sharding example
|
79
91
|
|
80
|
-
|
92
|
+
Some models are in the core DB, and others in shard DBs. Shard is selected based on a user attribute. For core models use the default ActiveRecord connection and for sharded models define and use Octoshark connections.
|
81
93
|
|
82
|
-
|
94
|
+
Switch the connection in a controller with an around filter:
|
83
95
|
|
84
96
|
```ruby
|
85
|
-
# before_filter :find_user
|
86
97
|
around_filter :select_shard
|
87
98
|
|
88
99
|
def select_shard(&block)
|
89
|
-
|
100
|
+
CONN_MANAGER.with_connection(current_user.shard, &block)
|
90
101
|
end
|
91
102
|
```
|
92
103
|
|
93
|
-
|
104
|
+
Similar approach applies to other application entry-points like background jobs.
|
94
105
|
|
95
106
|
|
96
|
-
## Master-Slave
|
107
|
+
## Master-Slave example
|
97
108
|
|
98
|
-
|
109
|
+
All models are in master and slave databases. For master models use the default ActiveRecord connection and for slave models define and use Octoshark connections.
|
99
110
|
|
100
111
|
```ruby
|
101
112
|
class ActiveRecord::Base
|
102
113
|
def self.connection
|
103
|
-
# Some rake tasks like `rake db:create` does not load initializers,
|
104
|
-
# and because we're overriding ActiveRecord::Base.connection,
|
105
|
-
# we need to make sure Octoshark is configured before using it.
|
106
|
-
Octoshark.configure(configs) unless Octoshark.configured?
|
107
|
-
|
108
114
|
# Return the current connection (from with_connection block) or default one
|
109
|
-
|
115
|
+
CONN_MANAGER.current_or_default_connection
|
110
116
|
end
|
111
117
|
end
|
112
118
|
```
|
113
119
|
|
114
|
-
|
120
|
+
`CONN_MANAGER.current_or_default_connection` method returns the current connection while in `with_connection` block or the default ActiveRecord connection when outside.
|
115
121
|
|
116
122
|
|
117
|
-
##
|
123
|
+
## Multi-tenant example
|
118
124
|
|
119
|
-
|
125
|
+
Some models are in the core DB, and others in user's own dedicated database. For core models use the default ActiveRecord connection and for tenant models can use Octoshark's mechanism to create new temporary connection.
|
120
126
|
|
121
|
-
|
127
|
+
Switch the connection in a controller with an around filter:
|
128
|
+
|
129
|
+
```ruby
|
130
|
+
# in initializer
|
131
|
+
CONN_MANAGER = Octoshark::ConnectionManager.new
|
132
|
+
|
133
|
+
# in controller
|
134
|
+
around_filter :select_shard
|
135
|
+
|
136
|
+
def select_shard(&block)
|
137
|
+
CONN_MANAGER.with_new_connection(name, config, reusable: false, &block)
|
138
|
+
end
|
139
|
+
```
|
140
|
+
|
141
|
+
`CONN_MANAGER.with_new_connection` method creates a temporary connection that will automatically disconnect. If you want to reuse it in subsequent connection switches, set `reusable: true` and it will be added to the connection manager and reused with the next calls. Depends on the use-case and what's preferable. In test environment usually you would want to set it to `reusable` so that database cleaner can clean data with transaction strategy.
|
142
|
+
|
143
|
+
|
144
|
+
## Octoshark.reset_connection_managers!
|
145
|
+
|
146
|
+
Whenever ActiveRecord::Base calls `establish_connection` (usually by an ancestor process that must have subsequently forked), `Octoshark.reset_connection_managers!` is automatically called to re-establish the Octoshark connections. It prevents `ActiveRecord::ConnectionNotEstablished` in the scenarios like:
|
122
147
|
|
123
148
|
* Unicorn before/after fork
|
124
149
|
* Spring prefork/serve
|
@@ -127,7 +152,7 @@ Few examples where database connections are re-established:
|
|
127
152
|
|
128
153
|
## Database Cleaner
|
129
154
|
|
130
|
-
|
155
|
+
RSpec example on how to clean default and Octoshark data with Database Cleaner:
|
131
156
|
|
132
157
|
```ruby
|
133
158
|
config.before(:suite) do
|
@@ -146,16 +171,21 @@ config.after(:each) do
|
|
146
171
|
end
|
147
172
|
|
148
173
|
def setup_database_cleaner
|
149
|
-
|
150
|
-
|
174
|
+
DatabaseCleaner[:active_record, {connection: ActiveRecord::Base.connection_pool}]
|
175
|
+
Octoshark.connection_managers.each do |manager|
|
176
|
+
manager.connection_pools.each_pair do |connection_name, connection_pool|
|
177
|
+
DatabaseCleaner[:active_record, {connection: connection_pool}]
|
178
|
+
end
|
151
179
|
end
|
152
180
|
end
|
153
181
|
```
|
154
182
|
|
183
|
+
|
155
184
|
## Logo
|
156
185
|
|
157
186
|
Thanks to [@saschamt](https://github.com/saschamt) for Octoshark logo design. :)
|
158
187
|
|
188
|
+
|
159
189
|
## Contributing
|
160
190
|
|
161
191
|
1. Fork it ( http://github.com/dalibor/octoshark/fork )
|
data/lib/octoshark.rb
CHANGED
@@ -3,55 +3,23 @@ require 'active_record'
|
|
3
3
|
require 'octoshark/active_record_extensions'
|
4
4
|
|
5
5
|
module Octoshark
|
6
|
-
autoload :
|
6
|
+
autoload :ConnectionManager, 'octoshark/connection_manager'
|
7
|
+
autoload :Error, 'octoshark/error'
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
# Octoshark needs to keep track of all connection managers in order to
|
10
|
+
# automatically reconnect on connection establish.
|
11
|
+
@@connection_managers = []
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
delegate :connection_pools,
|
16
|
-
:current_or_default_connection,
|
17
|
-
:disconnect!,
|
18
|
-
:find_connection_pool,
|
19
|
-
:with_connection,
|
20
|
-
:without_connection,
|
21
|
-
:current_connection,
|
22
|
-
:current_connection?,
|
23
|
-
to: :switcher
|
24
|
-
|
25
|
-
def configure(configs)
|
26
|
-
@configs = configs
|
27
|
-
@switcher = ConnectionSwitcher.new(configs)
|
28
|
-
end
|
29
|
-
|
30
|
-
def reset!
|
31
|
-
return unless configured?
|
32
|
-
disconnect!
|
33
|
-
@confings = nil
|
34
|
-
@switcher = nil
|
35
|
-
Thread.current[OCTOSHARK] = nil
|
36
|
-
end
|
37
|
-
|
38
|
-
def reload!
|
39
|
-
raise_not_configured_error unless @configs
|
40
|
-
disconnect!
|
41
|
-
@switcher = ConnectionSwitcher.new(@configs)
|
42
|
-
end
|
43
|
-
|
44
|
-
def configured?
|
45
|
-
!@switcher.nil?
|
46
|
-
end
|
13
|
+
def self.connection_managers
|
14
|
+
@@connection_managers
|
15
|
+
end
|
47
16
|
|
48
|
-
|
49
|
-
|
50
|
-
|
17
|
+
def self.reset_connection_managers!
|
18
|
+
connection_managers.map(&:reset!)
|
19
|
+
end
|
51
20
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
21
|
+
def self.disconnect!
|
22
|
+
connection_managers.map(&:disconnect!)
|
23
|
+
@@connection_managers = []
|
56
24
|
end
|
57
25
|
end
|
@@ -9,9 +9,13 @@ module Octoshark
|
|
9
9
|
end
|
10
10
|
|
11
11
|
module ClassMethods
|
12
|
+
# When a connection is established in an ancestor process that must have
|
13
|
+
# subsequently forked, ActiveRecord establishes a new connection because
|
14
|
+
# it can't reuse the existing one. When that happens, we need to reconnect
|
15
|
+
# Octoshark connection managers.
|
12
16
|
def establish_connection_with_octoshark(*args)
|
13
17
|
establish_connection_without_octoshark(*args)
|
14
|
-
Octoshark.
|
18
|
+
Octoshark.reset_connection_managers!
|
15
19
|
end
|
16
20
|
end
|
17
21
|
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Octoshark
|
2
|
+
class ConnectionManager
|
3
|
+
|
4
|
+
attr_reader :connection_pools
|
5
|
+
|
6
|
+
def initialize(configs = {})
|
7
|
+
@configs = configs.with_indifferent_access
|
8
|
+
setup_connection_pools
|
9
|
+
|
10
|
+
Octoshark.connection_managers << self
|
11
|
+
end
|
12
|
+
|
13
|
+
def reset!
|
14
|
+
disconnect!
|
15
|
+
setup_connection_pools
|
16
|
+
end
|
17
|
+
|
18
|
+
def current_connection
|
19
|
+
Thread.current[identifier] || raise(Octoshark::Error::NoCurrentConnection, "No current connection")
|
20
|
+
end
|
21
|
+
|
22
|
+
def current_connection?
|
23
|
+
!Thread.current[identifier].nil?
|
24
|
+
end
|
25
|
+
|
26
|
+
def current_or_default_connection
|
27
|
+
Thread.current[identifier] || ActiveRecord::Base.connection_pool.connection
|
28
|
+
end
|
29
|
+
|
30
|
+
def with_connection(name, &block)
|
31
|
+
connection_pool = find_connection_pool(name)
|
32
|
+
with_connection_pool(name, connection_pool, &block)
|
33
|
+
end
|
34
|
+
|
35
|
+
def with_new_connection(name, config, reusable: false, &block)
|
36
|
+
if reusable
|
37
|
+
connection_pool = @connection_pools[name] ||= create_connection_pool(config)
|
38
|
+
with_connection_pool(name, connection_pool, &block)
|
39
|
+
else
|
40
|
+
connection_pool = create_connection_pool(config)
|
41
|
+
with_connection_pool(name, connection_pool, &block).tap do
|
42
|
+
connection_pool.disconnect!
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def without_connection(&block)
|
48
|
+
change_connection_reference(nil) do
|
49
|
+
yield
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def find_connection_pool(name)
|
54
|
+
@connection_pools[name] || raise(Octoshark::Error::NoConnection, "No such database connection '#{name}'")
|
55
|
+
end
|
56
|
+
|
57
|
+
def disconnect!
|
58
|
+
@connection_pools.values.each do |connection_pool|
|
59
|
+
connection_pool.disconnect!
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def identifier
|
64
|
+
@identifier ||= "octoshark_#{Process.pid}"
|
65
|
+
end
|
66
|
+
|
67
|
+
private
|
68
|
+
def spec_class
|
69
|
+
if defined?(ActiveRecord::ConnectionAdapters::ConnectionSpecification)
|
70
|
+
spec_class = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
71
|
+
else
|
72
|
+
spec_class = ActiveRecord::Base::ConnectionSpecification
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def change_connection_reference(connection, &block)
|
77
|
+
previous_connection = Thread.current[identifier]
|
78
|
+
Thread.current[identifier] = connection
|
79
|
+
|
80
|
+
begin
|
81
|
+
yield
|
82
|
+
ensure
|
83
|
+
Thread.current[identifier] = previous_connection
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def setup_connection_pools
|
88
|
+
@connection_pools = HashWithIndifferentAccess.new
|
89
|
+
|
90
|
+
@configs.each_pair do |name, config|
|
91
|
+
@connection_pools[name] = create_connection_pool(config)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def create_connection_pool(config)
|
96
|
+
spec = spec_class.new(config, "#{config[:adapter]}_connection")
|
97
|
+
ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
|
98
|
+
end
|
99
|
+
|
100
|
+
def with_connection_pool(name, connection_pool, &block)
|
101
|
+
connection_pool.with_connection do |connection|
|
102
|
+
connection.connection_name = name
|
103
|
+
|
104
|
+
change_connection_reference(connection) do
|
105
|
+
yield(connection)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
data/lib/octoshark/version.rb
CHANGED
@@ -2,23 +2,14 @@ require 'spec_helper'
|
|
2
2
|
require 'logger'
|
3
3
|
|
4
4
|
describe "ActiveRecord Extensions" do
|
5
|
-
it "reloads connection pools when establishing a new connection" do
|
6
|
-
Octoshark.configure(configs)
|
7
|
-
|
8
|
-
spec = ActiveRecord::Base.remove_connection
|
9
|
-
ActiveRecord::Base.establish_connection(spec)
|
10
|
-
|
11
|
-
expect(Octoshark.find_connection_pool(:default)).to eq(ActiveRecord::Base.connection_pool)
|
12
|
-
end
|
13
|
-
|
14
5
|
it "logs current connection name" do
|
15
6
|
io = StringIO.new
|
16
7
|
logger = Logger.new(io)
|
17
8
|
|
18
9
|
ActiveRecord::Base.logger = logger
|
19
10
|
|
20
|
-
Octoshark.
|
21
|
-
|
11
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
12
|
+
manager.with_connection(:db1) do |connection|
|
22
13
|
connection.execute("SELECT 1")
|
23
14
|
end
|
24
15
|
|
@@ -33,8 +24,8 @@ describe "ActiveRecord Extensions" do
|
|
33
24
|
|
34
25
|
ActiveRecord::Base.logger = logger
|
35
26
|
|
36
|
-
Octoshark.
|
37
|
-
|
27
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
28
|
+
manager.with_connection(:db1) do |connection|
|
38
29
|
ActiveRecord::Base.connection.execute("SELECT 1")
|
39
30
|
end
|
40
31
|
|
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Octoshark::ConnectionManager do
|
4
|
+
describe "#initialize" do
|
5
|
+
it "initializes connection manager with default connection" do
|
6
|
+
manager = Octoshark::ConnectionManager.new
|
7
|
+
|
8
|
+
expect(manager.connection_pools.length).to eq(0)
|
9
|
+
expect(manager.connection_pools[:default]).to be_nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "initializes connection manager with custom connections" do
|
13
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
14
|
+
|
15
|
+
expect(manager.connection_pools.length).to eq(2)
|
16
|
+
expect(manager.connection_pools[:db1]).to be_an_instance_of(ActiveRecord::ConnectionAdapters::ConnectionPool)
|
17
|
+
expect(manager.connection_pools[:db2]).to be_an_instance_of(ActiveRecord::ConnectionAdapters::ConnectionPool)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "accepts configs with string keys" do
|
21
|
+
configs = { 'db1' => { 'adapter' => "sqlite3", 'database' => "tmp/db1.sqlite" } }
|
22
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
23
|
+
|
24
|
+
expect { manager.connection_pools[:db1].connection }.not_to raise_error
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "#current_connection" do
|
29
|
+
it "returns last used connection as current one" do
|
30
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
31
|
+
manager.with_connection(:db1) do |connection|
|
32
|
+
expect(manager.current_connection).to eq(connection)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "raises error when no current connection" do
|
37
|
+
manager = Octoshark::ConnectionManager.new
|
38
|
+
|
39
|
+
expect { manager.current_connection }.to raise_error(Octoshark::Error::NoCurrentConnection)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe "#current_connection?" do
|
44
|
+
it "returns true if current one" do
|
45
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
46
|
+
manager.with_connection(:db1) do
|
47
|
+
expect(manager.current_connection?).to be_truthy
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "returns false if no current one" do
|
52
|
+
manager = Octoshark::ConnectionManager.new
|
53
|
+
|
54
|
+
expect(manager.current_connection?).to be_falsey
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
describe "#current_or_default_connection" do
|
59
|
+
it "returns current connection" do
|
60
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
61
|
+
manager.with_connection(:db1) do |db1|
|
62
|
+
expect(manager.current_or_default_connection).to eq(db1)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
it "returns default connection when no current connection" do
|
67
|
+
manager = Octoshark::ConnectionManager.new
|
68
|
+
|
69
|
+
expect(manager.current_or_default_connection).to eq(ActiveRecord::Base.connection_pool.connection)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe '#find_connection_pool' do
|
74
|
+
it "can find connection pool by name" do
|
75
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
76
|
+
expect(manager.find_connection_pool(:db1)).to be_an_instance_of(ActiveRecord::ConnectionAdapters::ConnectionPool)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "raises Octoshark::Error::NoConnection when no pool with that name" do
|
80
|
+
manager = Octoshark::ConnectionManager.new({})
|
81
|
+
expect { manager.find_connection_pool(:invalid) }.to raise_error(Octoshark::Error::NoConnection)
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
describe '#with_connection' do
|
86
|
+
it "can use multiple connections" do
|
87
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
88
|
+
|
89
|
+
manager.with_connection(:db1) do
|
90
|
+
expect(db(manager.current_connection)).to eq("db1")
|
91
|
+
end
|
92
|
+
|
93
|
+
manager.with_connection(:db2) do
|
94
|
+
expect(db(manager.current_connection)).to eq("db2")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
it "can nest connection" do
|
99
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
100
|
+
|
101
|
+
manager.with_connection(:db1) do
|
102
|
+
expect(db(manager.current_connection)).to eq("db1")
|
103
|
+
|
104
|
+
manager.with_connection(:db2) do
|
105
|
+
expect(db(manager.current_connection)).to eq("db2")
|
106
|
+
end
|
107
|
+
|
108
|
+
expect(db(manager.current_connection)).to eq("db1")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
it "returns value from execution" do
|
113
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
114
|
+
result = manager.with_connection(:db1) { |connection| connection.execute("SELECT 1") }
|
115
|
+
expect(result).to eq([{"1"=>1, 0=>1}])
|
116
|
+
end
|
117
|
+
|
118
|
+
it "raises Octoshark::Error::NoConnection" do
|
119
|
+
manager = Octoshark::ConnectionManager.new({})
|
120
|
+
|
121
|
+
expect { manager.with_connection(:invalid) }.to raise_error(Octoshark::Error::NoConnection)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe "#with_new_connection" do
|
126
|
+
it "creates temporary connection" do
|
127
|
+
manager = Octoshark::ConnectionManager.new
|
128
|
+
result = manager.with_new_connection(:db1, configs[:db1]) { |connection| connection.execute("SELECT 1") }
|
129
|
+
|
130
|
+
expect(manager.connection_pools).to be_blank
|
131
|
+
end
|
132
|
+
|
133
|
+
it "returns query results with temporary connection" do
|
134
|
+
manager = Octoshark::ConnectionManager.new
|
135
|
+
result = manager.with_new_connection(:db1, configs[:db1]) { |connection| connection.execute("SELECT 1") }
|
136
|
+
|
137
|
+
expect(result).to eq([{"1"=>1, 0=>1}])
|
138
|
+
end
|
139
|
+
|
140
|
+
it "creates persistent connection" do
|
141
|
+
connection_id = nil
|
142
|
+
manager = Octoshark::ConnectionManager.new
|
143
|
+
expect(manager.connection_pools.length).to eq(0)
|
144
|
+
|
145
|
+
manager.with_new_connection(:db1, configs[:db1], reusable: true) do |connection|
|
146
|
+
connection_id = connection.object_id
|
147
|
+
end
|
148
|
+
expect(manager.connection_pools.length).to eq(1)
|
149
|
+
|
150
|
+
manager.with_new_connection(:db1, configs[:db1], reusable: true) do |connection|
|
151
|
+
expect(connection.object_id).to eq(connection_id)
|
152
|
+
end
|
153
|
+
expect(manager.connection_pools.length).to eq(1)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "returns query results with persistent connection" do
|
157
|
+
manager = Octoshark::ConnectionManager.new
|
158
|
+
|
159
|
+
result = manager.with_new_connection(:db1, configs[:db1], reusable: true) { |connection| connection.execute("SELECT 1") }
|
160
|
+
expect(result).to eq([{"1"=>1, 0=>1}])
|
161
|
+
|
162
|
+
result = manager.with_new_connection(:db1, configs[:db1], reusable: true) { |connection| connection.execute("SELECT 1") }
|
163
|
+
expect(result).to eq([{"1"=>1, 0=>1}])
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe '#without_connection' do
|
168
|
+
it "can reset current connection temporarily inside nested connection block" do
|
169
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
170
|
+
|
171
|
+
manager.with_connection(:db1) do
|
172
|
+
expect(db(manager.current_connection)).to eq("db1")
|
173
|
+
|
174
|
+
manager.without_connection do
|
175
|
+
expect { manager.current_connection }.to raise_error(Octoshark::Error::NoCurrentConnection)
|
176
|
+
end
|
177
|
+
|
178
|
+
expect(db(manager.current_connection)).to eq("db1")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
describe "#disconnect!" do
|
184
|
+
it "removes all connections from connection pools" do
|
185
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
186
|
+
|
187
|
+
manager.with_connection(:db1) { |connection| connection.execute("SELECT 1") }
|
188
|
+
expect(manager.find_connection_pool(:db1)).to be_connected
|
189
|
+
|
190
|
+
manager.disconnect!
|
191
|
+
|
192
|
+
expect(manager.find_connection_pool(:db1)).to_not be_connected
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe ".reset!" do
|
197
|
+
it "gets new connection pools ready to rock" do
|
198
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
199
|
+
|
200
|
+
manager.with_connection(:db1) { |connection| connection.execute("SELECT 1") }
|
201
|
+
expect(manager.connection_pools[:db1].connections.count).to eq(1)
|
202
|
+
|
203
|
+
manager.reset!
|
204
|
+
|
205
|
+
expect(manager.connection_pools[:db1].connections.count).to eq(0)
|
206
|
+
|
207
|
+
manager.with_connection(:db1) { |connection| connection.execute("SELECT 1") }
|
208
|
+
expect(manager.connection_pools[:db1].connections.count).to eq(1)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
data/spec/octoshark_spec.rb
CHANGED
@@ -2,92 +2,39 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Octoshark do
|
4
4
|
|
5
|
-
describe ".
|
6
|
-
it "
|
7
|
-
Octoshark.
|
5
|
+
describe ".reset_connection_managers!" do
|
6
|
+
it "resets connection managers" do
|
7
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
8
|
+
old_pools = manager.connection_pools.map(&:object_id)
|
8
9
|
|
9
|
-
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
describe ".reset!" do
|
14
|
-
it "removes connection switcher" do
|
15
|
-
Octoshark.configure({})
|
16
|
-
Octoshark.reset!
|
17
|
-
|
18
|
-
expect { Octoshark.switcher }.to raise_error(Octoshark::NotConfiguredError)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "cleans octoshark thread key" do
|
22
|
-
Octoshark.configure({})
|
23
|
-
Octoshark.reset!
|
10
|
+
Octoshark.reset_connection_managers!
|
24
11
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
it "cleans old connections" do
|
29
|
-
check_connections_clean_up { Octoshark.reset! }
|
12
|
+
new_pools = manager.connection_pools.map(&:object_id)
|
13
|
+
expect(new_pools).to_not eq(old_pools)
|
30
14
|
end
|
31
15
|
end
|
32
16
|
|
33
|
-
describe ".
|
34
|
-
it "
|
35
|
-
Octoshark.
|
36
|
-
switcher = Octoshark.switcher
|
17
|
+
describe ".disconnect!" do
|
18
|
+
it "disconnects connection managers" do
|
19
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
37
20
|
|
38
|
-
Octoshark.
|
21
|
+
Octoshark.disconnect!
|
39
22
|
|
40
|
-
expect(Octoshark.
|
41
|
-
expect(Octoshark.switcher).to_not eq(switcher)
|
23
|
+
expect(Octoshark.connection_managers).to be_blank
|
42
24
|
end
|
43
25
|
|
44
|
-
it "
|
45
|
-
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
describe ".configured?" do
|
50
|
-
it "is not configured by default" do
|
51
|
-
expect(Octoshark.configured?).to be_falsey
|
52
|
-
end
|
53
|
-
|
54
|
-
it "is configured is switcher is configured" do
|
55
|
-
Octoshark.configure({})
|
56
|
-
|
57
|
-
expect(Octoshark.configured?).to be_truthy
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
describe ".switcher" do
|
62
|
-
it "returns connection switcher" do
|
63
|
-
Octoshark.configure({})
|
64
|
-
|
65
|
-
expect(Octoshark.switcher).to be_an_instance_of(Octoshark::ConnectionSwitcher)
|
66
|
-
end
|
26
|
+
it "cleans old connections" do
|
27
|
+
manager = Octoshark::ConnectionManager.new(configs)
|
67
28
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
29
|
+
manager.with_connection(:db1) { |connection| connection.execute("SELECT 1") }
|
30
|
+
manager.with_connection(:db2) { |connection| connection.execute("SELECT 1") }
|
31
|
+
expect(manager.connection_pools[:db1].connections.count).to eq(1)
|
32
|
+
expect(manager.connection_pools[:db2].connections.count).to eq(1)
|
72
33
|
|
73
|
-
|
74
|
-
:connection_pools,
|
75
|
-
:current_connection,
|
76
|
-
:current_connection?,
|
77
|
-
:current_or_default_connection,
|
78
|
-
:disconnect!,
|
79
|
-
:find_connection_pool,
|
80
|
-
:with_connection,
|
81
|
-
:without_connection,
|
82
|
-
].each do |method_name|
|
83
|
-
describe ".#{method_name}" do
|
84
|
-
it "delegates #{method_name} to connection switcher" do
|
85
|
-
Octoshark.configure({})
|
86
|
-
expect(Octoshark.switcher).to respond_to(method_name)
|
87
|
-
expect(Octoshark.switcher).to receive(method_name)
|
34
|
+
Octoshark.disconnect!
|
88
35
|
|
89
|
-
|
90
|
-
|
36
|
+
expect(manager.connection_pools[:db1].connections.count).to eq(0)
|
37
|
+
expect(manager.connection_pools[:db2].connections.count).to eq(0)
|
91
38
|
end
|
92
39
|
end
|
93
40
|
end
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/helpers.rb
CHANGED
@@ -13,16 +13,4 @@ module Helpers
|
|
13
13
|
split('/').last.
|
14
14
|
split('.').first
|
15
15
|
end
|
16
|
-
|
17
|
-
def check_connections_clean_up
|
18
|
-
Octoshark.configure({})
|
19
|
-
switcher = Octoshark.switcher
|
20
|
-
|
21
|
-
Octoshark.with_connection(:default) { |connection| connection.execute("SELECT 1") }
|
22
|
-
expect(switcher.connection_pools.map { |_, c| c.connections.count }.sum).to eq(1)
|
23
|
-
|
24
|
-
yield
|
25
|
-
|
26
|
-
expect(switcher.connection_pools.map { |_, c| c.connections.count }.sum).to eq(0)
|
27
|
-
end
|
28
16
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: octoshark
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dalibor Nasevic
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-06-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -114,14 +114,16 @@ files:
|
|
114
114
|
- gemfiles/rails3.2.gemfile
|
115
115
|
- gemfiles/rails3.gemfile
|
116
116
|
- gemfiles/rails4.1.gemfile
|
117
|
+
- gemfiles/rails4.2.gemfile
|
117
118
|
- gemfiles/rails4.gemfile
|
118
119
|
- lib/octoshark.rb
|
119
120
|
- lib/octoshark/active_record_extensions.rb
|
120
|
-
- lib/octoshark/
|
121
|
+
- lib/octoshark/connection_manager.rb
|
122
|
+
- lib/octoshark/error.rb
|
121
123
|
- lib/octoshark/version.rb
|
122
124
|
- octoshark.gemspec
|
123
125
|
- spec/octoshark/active_record_extensions_spec.rb
|
124
|
-
- spec/octoshark/
|
126
|
+
- spec/octoshark/connection_manager_spec.rb
|
125
127
|
- spec/octoshark_spec.rb
|
126
128
|
- spec/spec_helper.rb
|
127
129
|
- spec/support/helpers.rb
|
@@ -151,7 +153,7 @@ specification_version: 4
|
|
151
153
|
summary: Octoshark is an ActiveRecord connection switcher
|
152
154
|
test_files:
|
153
155
|
- spec/octoshark/active_record_extensions_spec.rb
|
154
|
-
- spec/octoshark/
|
156
|
+
- spec/octoshark/connection_manager_spec.rb
|
155
157
|
- spec/octoshark_spec.rb
|
156
158
|
- spec/spec_helper.rb
|
157
159
|
- spec/support/helpers.rb
|
@@ -1,77 +0,0 @@
|
|
1
|
-
module Octoshark
|
2
|
-
class ConnectionSwitcher
|
3
|
-
|
4
|
-
attr_reader :connection_pools
|
5
|
-
|
6
|
-
def initialize(configs = {})
|
7
|
-
configs = configs.with_indifferent_access
|
8
|
-
@default_pool = ActiveRecord::Base.connection_pool
|
9
|
-
@connection_pools = { default: @default_pool }.with_indifferent_access
|
10
|
-
|
11
|
-
configs.each_pair do |name, config|
|
12
|
-
spec = spec_class.new(config, "#{config[:adapter]}_connection")
|
13
|
-
@connection_pools[name] = ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
def current_connection
|
18
|
-
Thread.current[OCTOSHARK] || raise(NoCurrentConnectionError, "No current connection, use Octoshark.with_connection")
|
19
|
-
end
|
20
|
-
|
21
|
-
def current_connection?
|
22
|
-
!Thread.current[OCTOSHARK].nil?
|
23
|
-
end
|
24
|
-
|
25
|
-
def current_or_default_connection
|
26
|
-
Thread.current[OCTOSHARK] || @default_pool.connection
|
27
|
-
end
|
28
|
-
|
29
|
-
def with_connection(name, &block)
|
30
|
-
find_connection_pool(name).with_connection do |connection|
|
31
|
-
connection.connection_name = name
|
32
|
-
|
33
|
-
change_connection_reference(connection) do
|
34
|
-
yield(connection)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def without_connection(&block)
|
40
|
-
connection = nil
|
41
|
-
|
42
|
-
change_connection_reference(connection) do
|
43
|
-
yield(connection)
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
def find_connection_pool(name)
|
48
|
-
@connection_pools[name] || raise(NoConnectionError, "No such database connection '#{name}'")
|
49
|
-
end
|
50
|
-
|
51
|
-
def disconnect!
|
52
|
-
@connection_pools.values.each do |connection_pool|
|
53
|
-
connection_pool.disconnect!
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
def spec_class
|
59
|
-
if defined?(ActiveRecord::ConnectionAdapters::ConnectionSpecification)
|
60
|
-
spec_class = ActiveRecord::ConnectionAdapters::ConnectionSpecification
|
61
|
-
else
|
62
|
-
spec_class = ActiveRecord::Base::ConnectionSpecification
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
def change_connection_reference(connection)
|
67
|
-
previous_connection = Thread.current[OCTOSHARK]
|
68
|
-
Thread.current[OCTOSHARK] = connection
|
69
|
-
|
70
|
-
begin
|
71
|
-
yield
|
72
|
-
ensure
|
73
|
-
Thread.current[OCTOSHARK] = previous_connection
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
@@ -1,167 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
|
3
|
-
describe Octoshark::ConnectionSwitcher do
|
4
|
-
describe "#initialize" do
|
5
|
-
it "initializes connection switcher with default connection" do
|
6
|
-
switcher = Octoshark::ConnectionSwitcher.new
|
7
|
-
conn = ActiveRecord::Base.connection
|
8
|
-
|
9
|
-
expect(switcher.connection_pools.length).to eq(1)
|
10
|
-
expect(switcher.connection_pools[:default]).to be_an_instance_of(ActiveRecord::ConnectionAdapters::ConnectionPool)
|
11
|
-
end
|
12
|
-
|
13
|
-
it "initializes connection switcher with custom connections" do
|
14
|
-
switcher = Octoshark::ConnectionSwitcher.new(configs)
|
15
|
-
|
16
|
-
expect(switcher.connection_pools.length).to eq(3)
|
17
|
-
expect(switcher.connection_pools[:default]).to be_an_instance_of(ActiveRecord::ConnectionAdapters::ConnectionPool)
|
18
|
-
expect(switcher.connection_pools[:db1]).to be_an_instance_of(ActiveRecord::ConnectionAdapters::ConnectionPool)
|
19
|
-
end
|
20
|
-
|
21
|
-
it "accepts configs with string keys" do
|
22
|
-
configs = { 'db1' => { 'adapter' => "sqlite3", 'database' => "tmp/db1.sqlite" } }
|
23
|
-
switcher = Octoshark::ConnectionSwitcher.new(configs)
|
24
|
-
|
25
|
-
expect { switcher.connection_pools[:db1].connection }.not_to raise_error
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
|
-
describe "#current_connection" do
|
30
|
-
it "returns last used connection as current one" do
|
31
|
-
switcher = Octoshark::ConnectionSwitcher.new(configs)
|
32
|
-
switcher.with_connection(:db1) do |connection|
|
33
|
-
expect(switcher.current_connection).to eq(connection)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
it "raises error when no current connection" do
|
38
|
-
switcher = Octoshark::ConnectionSwitcher.new
|
39
|
-
|
40
|
-
expect { switcher.current_connection }.to raise_error(Octoshark::NoCurrentConnectionError)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
describe "#current_connection?" do
|
45
|
-
it "returns true if current one" do
|
46
|
-
switcher = Octoshark::ConnectionSwitcher.new(configs)
|
47
|
-
switcher.with_connection(:db1) do |connection|
|
48
|
-
expect(switcher.current_connection?).to be_truthy
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
|
-
it "returns false if no current one" do
|
53
|
-
switcher = Octoshark::ConnectionSwitcher.new
|
54
|
-
|
55
|
-
expect(switcher.current_connection?).to be_falsey
|
56
|
-
end
|
57
|
-
end
|
58
|
-
|
59
|
-
describe "#current_or_default_connection" do
|
60
|
-
it "returns current connection" do
|
61
|
-
switcher = Octoshark::ConnectionSwitcher.new(configs)
|
62
|
-
switcher.with_connection(:db1) do |connection|
|
63
|
-
expect(switcher.current_or_default_connection).to eq(connection)
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
it "returns default connection when no current connection" do
|
68
|
-
switcher = Octoshark::ConnectionSwitcher.new
|
69
|
-
connection = switcher.find_connection_pool(:default).connection
|
70
|
-
|
71
|
-
expect(switcher.current_or_default_connection).to eq(connection)
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
describe '#find_connection_pool' do
|
76
|
-
it "can find connection pool by name" do
|
77
|
-
switcher = Octoshark::ConnectionSwitcher.new(configs)
|
78
|
-
expect(switcher.find_connection_pool(:db1)).to be_an_instance_of(ActiveRecord::ConnectionAdapters::ConnectionPool)
|
79
|
-
end
|
80
|
-
|
81
|
-
it "raises Octoshark::NoConnectionError when no pool with that name" do
|
82
|
-
switcher = Octoshark::ConnectionSwitcher.new({})
|
83
|
-
expect { switcher.find_connection_pool(:invalid) }.to raise_error(Octoshark::NoConnectionError)
|
84
|
-
end
|
85
|
-
end
|
86
|
-
|
87
|
-
describe '#with_connection' do
|
88
|
-
it "can select default connection" do
|
89
|
-
switcher = Octoshark::ConnectionSwitcher.new({})
|
90
|
-
|
91
|
-
switcher.with_connection(:default) do |connection|
|
92
|
-
expect(db(switcher.current_connection)).to eq("default")
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
it "can use multiple connections" do
|
97
|
-
switcher = Octoshark::ConnectionSwitcher.new(configs)
|
98
|
-
|
99
|
-
switcher.with_connection(:default) do |connection|
|
100
|
-
expect(db(switcher.current_connection)).to eq("default")
|
101
|
-
end
|
102
|
-
|
103
|
-
switcher.with_connection(:db1) do |connection|
|
104
|
-
expect(db(switcher.current_connection)).to eq("db1")
|
105
|
-
end
|
106
|
-
|
107
|
-
switcher.with_connection(:db2) do |connection|
|
108
|
-
expect(db(switcher.current_connection)).to eq("db2")
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
it "can nest connection" do
|
113
|
-
switcher = Octoshark::ConnectionSwitcher.new(configs)
|
114
|
-
|
115
|
-
switcher.with_connection(:db1) do |connection|
|
116
|
-
expect(db(switcher.current_connection)).to eq("db1")
|
117
|
-
|
118
|
-
switcher.with_connection(:db2) do |connection|
|
119
|
-
expect(db(switcher.current_connection)).to eq("db2")
|
120
|
-
end
|
121
|
-
|
122
|
-
expect(db(switcher.current_connection)).to eq("db1")
|
123
|
-
end
|
124
|
-
end
|
125
|
-
|
126
|
-
it "returns value from execution" do
|
127
|
-
switcher = Octoshark::ConnectionSwitcher.new({})
|
128
|
-
result = switcher.with_connection(:default) { |connection| connection.execute("SELECT 1") }
|
129
|
-
expect(result).to eq([{"1"=>1, 0=>1}])
|
130
|
-
end
|
131
|
-
|
132
|
-
it "raises Octoshark::NoConnectionError" do
|
133
|
-
switcher = Octoshark::ConnectionSwitcher.new({})
|
134
|
-
|
135
|
-
expect { switcher.with_connection(:invalid) }.to raise_error(Octoshark::NoConnectionError)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
describe '#without_connection' do
|
140
|
-
it "can reset current connection temporarily inside nested connection block" do
|
141
|
-
switcher = Octoshark::ConnectionSwitcher.new({})
|
142
|
-
|
143
|
-
switcher.with_connection(:default) do |connection|
|
144
|
-
expect(db(switcher.current_connection)).to eq("default")
|
145
|
-
|
146
|
-
switcher.without_connection do |connection|
|
147
|
-
expect { switcher.current_connection }.to raise_error(Octoshark::NoCurrentConnectionError)
|
148
|
-
end
|
149
|
-
|
150
|
-
expect(db(switcher.current_connection)).to eq("default")
|
151
|
-
end
|
152
|
-
end
|
153
|
-
end
|
154
|
-
|
155
|
-
describe "#disconnect!" do
|
156
|
-
it "removes all connections from connection pools" do
|
157
|
-
switcher = Octoshark::ConnectionSwitcher.new({})
|
158
|
-
|
159
|
-
switcher.with_connection(:default) { |connection| connection.execute("SELECT 1") }
|
160
|
-
expect(switcher.find_connection_pool(:default)).to be_connected
|
161
|
-
|
162
|
-
switcher.disconnect!
|
163
|
-
|
164
|
-
expect(switcher.find_connection_pool(:default)).to_not be_connected
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|