slaver 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +2 -0
- data/Appraisals +7 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +21 -0
- data/Makefile +31 -0
- data/README.md +161 -0
- data/Rakefile +6 -0
- data/config.ru +7 -0
- data/lib/slavable.rb +26 -0
- data/lib/slaver/config_handler.rb +46 -0
- data/lib/slaver/connection.rb +87 -0
- data/lib/slaver/pools_handler.rb +35 -0
- data/lib/slaver/proxy.rb +38 -0
- data/lib/slaver/proxy_methods.rb +61 -0
- data/lib/slaver/railtie.rb +9 -0
- data/lib/slaver/scope_proxy.rb +29 -0
- data/lib/slaver/version.rb +3 -0
- data/lib/slaver.rb +14 -0
- data/slaver.gemspec +35 -0
- metadata +247 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bc706e46c4f308443d1b9849251f2a8ecd6f4e71
|
4
|
+
data.tar.gz: edbdb3b2715e66375e92c6667f412dbd08c026de
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 523191d32e75fc20b2b3fe17ecc6f4efbb5161aff754a3e4fa622795b97f93237b077242907757dbccf6b391c2888a2a234e60fd861536b3abe625f3a428da1e
|
7
|
+
data.tar.gz: 0845dcdd9a65265866b507bc2543ebb87b14994e3fc17344102d94ede72e4632562f5df1505b2e6a30e77fd1fed0fb8e87b6367c3ed5dbd8b3c1f08e87a7e143
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/Appraisals
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
|
2
|
+
#### [Current]
|
3
|
+
|
4
|
+
|
5
|
+
#### v0.0.1
|
6
|
+
* 2015-11-03 [172eda3](../../commit/172eda3) - __(Denis Korobitcin)__ fix(slavable): add block support
|
7
|
+
* 2015-10-22 [b67f807](../../commit/b67f807) - __(Denis Korobitcin)__ feature: added slavable extension
|
8
|
+
* 2015-10-23 [9dc8cf0](../../commit/9dc8cf0) - __(Denis Korobitcin)__ chore(readme): fixed within section [skip ci]
|
9
|
+
* 2015-10-22 [bbb2535](../../commit/bbb2535) - __(Denis Korobitcin)__ chore: Big refactoring
|
10
|
+
* 2015-10-19 [b64de51](../../commit/b64de51) - __(Denis Korobitcin)__ feature: added main slaver logic
|
11
|
+
* 2015-10-19 [4441efa](../../commit/4441efa) - __(Artem Napolskih)__ Initial commit
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2015 Denis Korobitcin
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/Makefile
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
BUNDLE = bundle
|
2
|
+
BUNDLE_OPTIONS = -j 3
|
3
|
+
RSPEC = ${APPRAISAL} rspec
|
4
|
+
APPRAISAL = ${BUNDLE} exec appraisal
|
5
|
+
|
6
|
+
all: test
|
7
|
+
|
8
|
+
test: configs bundler appraisal
|
9
|
+
${RSPEC} 2>&1
|
10
|
+
|
11
|
+
define DATABASE_YML
|
12
|
+
test:
|
13
|
+
adapter: sqlite3
|
14
|
+
database: test
|
15
|
+
test_other:
|
16
|
+
adapter: sqlite3
|
17
|
+
database: test_other
|
18
|
+
endef
|
19
|
+
export DATABASE_YML
|
20
|
+
|
21
|
+
configs:
|
22
|
+
echo "$${DATABASE_YML}" > spec/internal/config/database.yml
|
23
|
+
|
24
|
+
bundler:
|
25
|
+
if ! gem list bundler -i > /dev/null; then \
|
26
|
+
gem install bundler; \
|
27
|
+
fi
|
28
|
+
${BUNDLE} install ${BUNDLE_OPTIONS}
|
29
|
+
|
30
|
+
appraisal:
|
31
|
+
${APPRAISAL} install
|
data/README.md
ADDED
@@ -0,0 +1,161 @@
|
|
1
|
+
[![Dolly](http://dolly.railsc.ru/badges/abak-press/slaver/master)](http://dolly.railsc.ru/projects/129/builds/latest/?ref=master)
|
2
|
+
|
3
|
+
# Slaver
|
4
|
+
|
5
|
+
Welcome to slaver!
|
6
|
+
|
7
|
+
It's a simple gem for rails application within multi-database environment.
|
8
|
+
It allows you to change your current connection to other database configuration.
|
9
|
+
Some ideas was inspired by [octopus](https://github.com/tchandy/octopus).
|
10
|
+
|
11
|
+
## WARNING
|
12
|
+
|
13
|
+
It was tested only on `rails 3` and `ruby 1.9.3`. Other configurations may work or may not:)
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
gem 'slaver'
|
21
|
+
```
|
22
|
+
|
23
|
+
And then execute:
|
24
|
+
|
25
|
+
$ bundle
|
26
|
+
|
27
|
+
Or install it yourself as:
|
28
|
+
|
29
|
+
$ gem install slaver
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
### Config
|
34
|
+
You must have other connection on your database.yml file. For example:
|
35
|
+
|
36
|
+
```yml
|
37
|
+
production:
|
38
|
+
adapter: pg
|
39
|
+
host: master
|
40
|
+
database: master
|
41
|
+
post: 11111
|
42
|
+
|
43
|
+
production_slave:
|
44
|
+
adapter: sqlite3
|
45
|
+
host: slave
|
46
|
+
database: slave
|
47
|
+
post: 11113
|
48
|
+
|
49
|
+
production_mysql:
|
50
|
+
adapter: mysql
|
51
|
+
user: me
|
52
|
+
host: somewhere_else
|
53
|
+
post: 11112
|
54
|
+
database: mysql
|
55
|
+
```
|
56
|
+
|
57
|
+
### Chain with AR
|
58
|
+
|
59
|
+
Only works with class/scope methods. Connection changed until query is perfomed. After that it'll swiched back to default connection.
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
SomeModel.on(:production_mysql).where(name: 'me').first
|
63
|
+
|
64
|
+
|
65
|
+
# or, if you name starting with you Rails.env it can be skipped
|
66
|
+
SomeModel.on(:mysql).where(name: 'me').to_a
|
67
|
+
```
|
68
|
+
|
69
|
+
### Execute block on other connection
|
70
|
+
|
71
|
+
Connection will be switched only for required class.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
# simple usage
|
75
|
+
SomeModel.within(:slave) do
|
76
|
+
SomeModel.where(name: 'me')
|
77
|
+
end
|
78
|
+
|
79
|
+
# It also can be combined with "on" method
|
80
|
+
SomeModel.within(:mysql) do
|
81
|
+
me = SomeModel.find_by_name('me')
|
82
|
+
SomeModel.on(:slave).find_by_name('me').update_attributes(me.attributes)
|
83
|
+
end
|
84
|
+
|
85
|
+
# it can execute multi-models queries on other connection
|
86
|
+
ActiveRecord::Base.within(:slave) do
|
87
|
+
SomeModel.where(name: 'me').first
|
88
|
+
OtherModel.where(name: 'me').first
|
89
|
+
end
|
90
|
+
```
|
91
|
+
|
92
|
+
### Execute whole method on any class on other connection
|
93
|
+
```ruby
|
94
|
+
class Some
|
95
|
+
extend Slavable
|
96
|
+
|
97
|
+
def some_method
|
98
|
+
Foo.create
|
99
|
+
f = Foo.where(...).first
|
100
|
+
other = SomeModel.where(...).first
|
101
|
+
f.update_attributes(...)
|
102
|
+
other.update_attributes(...)
|
103
|
+
...
|
104
|
+
end
|
105
|
+
|
106
|
+
def self.class_method
|
107
|
+
b = Bar.create
|
108
|
+
b.update_attributes(...)
|
109
|
+
Foo.where(bar: b)
|
110
|
+
....
|
111
|
+
end
|
112
|
+
|
113
|
+
switch :some_method, to: :other
|
114
|
+
|
115
|
+
# it also can be called on multiple methods and works with class_methods
|
116
|
+
|
117
|
+
switch :some_method, ..., to: :other
|
118
|
+
|
119
|
+
# for switching class method just use singleton class pattern:
|
120
|
+
class << self
|
121
|
+
extend Slavable
|
122
|
+
|
123
|
+
switch :class_method, ..., to: :other
|
124
|
+
end
|
125
|
+
....
|
126
|
+
end
|
127
|
+
|
128
|
+
# it''ll be executed with :other connection
|
129
|
+
Some.class_method
|
130
|
+
Some.new.some_method
|
131
|
+
```
|
132
|
+
|
133
|
+
### ACTUNG!!!!
|
134
|
+
|
135
|
+
If you connection does not exists, behavior may change dependent of you current Rails environment:
|
136
|
+
- `Rails.env == production`: It'll raise `ArgumentError`
|
137
|
+
- otherwise: It'll try to switch to default connection - `Rails.env`
|
138
|
+
|
139
|
+
### Missing features
|
140
|
+
|
141
|
+
1. 'on' with assosiations
|
142
|
+
2. Transaction safety
|
143
|
+
3. `on` method on instance
|
144
|
+
|
145
|
+
## Development
|
146
|
+
|
147
|
+
To run test on local machine use `make` command. For more info please reffer to Makefile.
|
148
|
+
|
149
|
+
## Contributing
|
150
|
+
|
151
|
+
1. Fork it ( https://github.com/abak-press/slaver/fork )
|
152
|
+
2. Create your feature branch (git checkout -b my-new-feature)
|
153
|
+
3. Commit your changes (git commit -am 'Add some feature')
|
154
|
+
4. Push to the branch (git push origin my-new-feature)
|
155
|
+
5. Create new Pull Request
|
156
|
+
|
157
|
+
|
158
|
+
|
159
|
+
## License
|
160
|
+
|
161
|
+
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
data/config.ru
ADDED
data/lib/slavable.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Slavable
|
2
|
+
def switch(*method_names)
|
3
|
+
options = method_names.pop
|
4
|
+
|
5
|
+
unless options.is_a?(Hash)
|
6
|
+
raise ArgumentError, 'Unable to detect "to" option, usage: "switch :method, :other, ..., to: :connection_name"'
|
7
|
+
end
|
8
|
+
|
9
|
+
method_names.each do |method|
|
10
|
+
aliased_method, punctuation = method.to_s.sub(/([?!=])$/, ''), $1
|
11
|
+
with_name = "#{aliased_method}_with_connection#{punctuation}"
|
12
|
+
without_name = "#{aliased_method}_without_connection#{punctuation}"
|
13
|
+
connection = options.with_indifferent_access.fetch(:to)
|
14
|
+
|
15
|
+
class_eval <<-eoruby, __FILE__, __LINE__ + 1
|
16
|
+
|
17
|
+
def #{with_name}(*args, &block)
|
18
|
+
::ActiveRecord::Base.within(:#{connection}) { #{without_name}(*args, &block) }
|
19
|
+
end
|
20
|
+
eoruby
|
21
|
+
|
22
|
+
alias_method without_name, method
|
23
|
+
alias_method method, with_name
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module Slaver
|
2
|
+
class ConfigHandler
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
attr_reader :block, :saved_block, :saved_config, :current_config
|
6
|
+
|
7
|
+
def run_with(klass, config_name, pools_handler)
|
8
|
+
config_name = prepare(config_name)
|
9
|
+
|
10
|
+
pools_handler.for_config(klass, config_name)
|
11
|
+
|
12
|
+
with_config(config_name) { yield }
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def with_config(config_name)
|
18
|
+
last_config = @current_config
|
19
|
+
@current_config = config_name
|
20
|
+
|
21
|
+
begin
|
22
|
+
yield
|
23
|
+
ensure
|
24
|
+
@current_config = last_config
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def prepare(config_name)
|
29
|
+
config_name = config_name.to_s
|
30
|
+
|
31
|
+
return config_name if ::ActiveRecord::Base.configurations.key?(config_name)
|
32
|
+
|
33
|
+
config_name = "#{Rails.env}_#{config_name}"
|
34
|
+
|
35
|
+
unless ::ActiveRecord::Base.configurations.key?(config_name)
|
36
|
+
if Rails.env.production?
|
37
|
+
raise ArgumentError, "Can't find #{config_name} on database configurations"
|
38
|
+
else
|
39
|
+
config_name = Rails.env
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
config_name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
module Slaver
|
2
|
+
module Connection
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
include ProxyMethods
|
7
|
+
|
8
|
+
class << self
|
9
|
+
delegate :current_config, to: :config_handler
|
10
|
+
delegate :pools, to: :pools_handler
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
# Public: Change database connection for next query
|
16
|
+
# WARNING: It'll change current DB connection until
|
17
|
+
# insert, select or execute methods call
|
18
|
+
#
|
19
|
+
# config_name - String or Symbol, name of config_section
|
20
|
+
#
|
21
|
+
# NOTE:
|
22
|
+
# if config was not found:
|
23
|
+
# 1) On production
|
24
|
+
# throws ArgumentError
|
25
|
+
# 2) Uses default configuration for current environment
|
26
|
+
#
|
27
|
+
# Exception safety:
|
28
|
+
# throws ArgumentError if no configuration was found
|
29
|
+
#
|
30
|
+
# Examples
|
31
|
+
#
|
32
|
+
# SomeModel.on(:slave).create(...)
|
33
|
+
# SomeModel.on(:slave).where(...).first
|
34
|
+
#
|
35
|
+
# It also can be chained with other 'on' methods
|
36
|
+
# SomeModel.on(:slave).on(:other).find_by(...)
|
37
|
+
#
|
38
|
+
# Returns self
|
39
|
+
def on(config_name)
|
40
|
+
ScopeProxy.new(self, config_name)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Public: Changes model's connection to database temporarily to execute block.
|
44
|
+
#
|
45
|
+
# config_name - String or Symbol, name of config_section
|
46
|
+
#
|
47
|
+
# NOTE:
|
48
|
+
# if config was not found:
|
49
|
+
# 1) On production
|
50
|
+
# throws ArgumentError
|
51
|
+
# 2) Uses default configuration for current environment
|
52
|
+
#
|
53
|
+
# Exception safety:
|
54
|
+
# throws ArgumentError if no configuration was found
|
55
|
+
#
|
56
|
+
# Examples
|
57
|
+
#
|
58
|
+
# SomeModel.within :test_slave do
|
59
|
+
# # do some computations here
|
60
|
+
# end
|
61
|
+
#
|
62
|
+
# It is also possible to nest database connection code
|
63
|
+
#
|
64
|
+
# SomeModel.within :slave do
|
65
|
+
# do some computations here
|
66
|
+
# SomeModel.within :slave2 do
|
67
|
+
# # some other computations go here
|
68
|
+
# end
|
69
|
+
# end
|
70
|
+
#
|
71
|
+
# Returns noting
|
72
|
+
def within(config_name)
|
73
|
+
config_handler.run_with(self, config_name, pools_handler) { yield }
|
74
|
+
end
|
75
|
+
|
76
|
+
private
|
77
|
+
|
78
|
+
def config_handler
|
79
|
+
ConfigHandler.instance
|
80
|
+
end
|
81
|
+
|
82
|
+
def pools_handler
|
83
|
+
PoolsHandler.instance
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Slaver
|
2
|
+
class PoolsHandler
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
def pools
|
6
|
+
@pools ||= {}
|
7
|
+
end
|
8
|
+
|
9
|
+
def for_config(klass, config_name)
|
10
|
+
@klass = klass
|
11
|
+
|
12
|
+
initialize_pool(config_name) unless pools[config_name]
|
13
|
+
|
14
|
+
self
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def initialize_pool(config_name)
|
20
|
+
if config_name == Rails.env
|
21
|
+
pools[config_name] = @klass.connection_pool_without_proxy
|
22
|
+
else
|
23
|
+
pools[config_name] = create_connection_pool(config_name)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def create_connection_pool(config_name)
|
28
|
+
config = ::ActiveRecord::Base.configurations[config_name]
|
29
|
+
config.symbolize_keys!
|
30
|
+
spec = ActiveRecord::Base::ConnectionSpecification.new(config, "#{config[:adapter]}_connection")
|
31
|
+
|
32
|
+
ActiveRecord::ConnectionAdapters::ConnectionPool.new(spec)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/slaver/proxy.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
module Slaver
|
2
|
+
class Proxy
|
3
|
+
include Singleton
|
4
|
+
|
5
|
+
attr_reader :connection_pool, :klass
|
6
|
+
|
7
|
+
def for_config(klass, config_name)
|
8
|
+
@klass = klass
|
9
|
+
@connection_pool = klass.pools[config_name]
|
10
|
+
|
11
|
+
self
|
12
|
+
end
|
13
|
+
|
14
|
+
def connected?
|
15
|
+
connection_pool.connected?
|
16
|
+
end
|
17
|
+
|
18
|
+
def clear_all_connections!
|
19
|
+
connection_pool.disconnect!
|
20
|
+
end
|
21
|
+
|
22
|
+
def clear_active_connections!
|
23
|
+
connection_pool.release_connection
|
24
|
+
end
|
25
|
+
|
26
|
+
def safe_connection
|
27
|
+
connection_pool.automatic_reconnect = true
|
28
|
+
if !connection_pool.connected? && klass.connection_without_proxy.query_cache_enabled
|
29
|
+
connection_pool.connection.enable_query_cache!
|
30
|
+
end
|
31
|
+
connection_pool.connection
|
32
|
+
end
|
33
|
+
|
34
|
+
def method_missing(method, *args, &block)
|
35
|
+
safe_connection.send(method, *args, &block)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Slaver
|
2
|
+
module ProxyMethods
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
class << self
|
7
|
+
alias_method_chain :connection, :proxy
|
8
|
+
alias_method_chain :connection_pool, :proxy
|
9
|
+
alias_method_chain :clear_all_connections!, :proxy
|
10
|
+
alias_method_chain :clear_active_connections!, :proxy
|
11
|
+
alias_method_chain :connected?, :proxy
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module ClassMethods
|
16
|
+
def connection_pool_with_proxy
|
17
|
+
if current_config
|
18
|
+
connection_proxy.connection_pool
|
19
|
+
else
|
20
|
+
connection_pool_without_proxy
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def connection_with_proxy
|
25
|
+
if current_config
|
26
|
+
connection_proxy
|
27
|
+
else
|
28
|
+
(connection_pool && connection_pool.connection)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def clear_active_connections_with_proxy!
|
33
|
+
if current_config
|
34
|
+
connection_proxy.clear_active_connections!
|
35
|
+
else
|
36
|
+
clear_active_connections_without_proxy!
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def clear_all_connections_with_proxy!
|
41
|
+
if current_config
|
42
|
+
connection_proxy.clear_all_connections!
|
43
|
+
else
|
44
|
+
clear_all_connections_without_proxy!
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def connected_with_proxy?
|
49
|
+
if current_config
|
50
|
+
connection_proxy.connected?
|
51
|
+
else
|
52
|
+
connected_without_proxy?
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def connection_proxy
|
57
|
+
Proxy.instance.for_config(self, current_config)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Slaver
|
2
|
+
class ScopeProxy
|
3
|
+
attr_reader :klass, :config_name
|
4
|
+
|
5
|
+
def initialize(klass, config_name)
|
6
|
+
@klass = klass
|
7
|
+
@config_name = config_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def on(config_name)
|
11
|
+
@config_name = config_name
|
12
|
+
self
|
13
|
+
end
|
14
|
+
|
15
|
+
def method_missing(method, *args, &block)
|
16
|
+
result = self
|
17
|
+
::ActiveRecord::Base.within(config_name) do
|
18
|
+
result = klass.send(method, *args, &block)
|
19
|
+
|
20
|
+
if result.is_a?(ActiveRecord::Relation)
|
21
|
+
@klass = result
|
22
|
+
return self
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
result
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/slaver.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'singleton'
|
3
|
+
require 'slaver/scope_proxy'
|
4
|
+
require 'slaver/config_handler'
|
5
|
+
require 'slaver/pools_handler'
|
6
|
+
require 'slaver/version'
|
7
|
+
require 'slaver/proxy'
|
8
|
+
require 'slaver/proxy_methods'
|
9
|
+
require 'slaver/connection'
|
10
|
+
require 'slaver/railtie'
|
11
|
+
require 'slavable'
|
12
|
+
|
13
|
+
module Slaver
|
14
|
+
end
|
data/slaver.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'slaver/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "slaver"
|
8
|
+
spec.version = Slaver::VERSION
|
9
|
+
spec.authors = ["Denis Korobitcin"]
|
10
|
+
spec.email = ["deniskorobitcin@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = %q{Instant change of connection in rails application.}
|
13
|
+
spec.homepage = "https://github.com/abak-press/slaver"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
17
|
+
spec.bindir = "exe"
|
18
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_runtime_dependency 'activerecord', '~> 3.1'
|
22
|
+
spec.add_runtime_dependency 'activesupport', '~> 3.1'
|
23
|
+
|
24
|
+
spec.add_development_dependency 'bundler'
|
25
|
+
spec.add_development_dependency 'rake'
|
26
|
+
spec.add_development_dependency 'rspec', '~> 3.3'
|
27
|
+
spec.add_development_dependency 'rspec-rails'
|
28
|
+
spec.add_development_dependency 'combustion', '~> 0.5'
|
29
|
+
spec.add_development_dependency 'appraisal'
|
30
|
+
spec.add_development_dependency 'pry-debugger'
|
31
|
+
spec.add_development_dependency 'shoulda-matchers', '< 3.0.0'
|
32
|
+
spec.add_development_dependency 'simplecov'
|
33
|
+
spec.add_development_dependency 'database_cleaner'
|
34
|
+
spec.add_development_dependency 'sqlite3'
|
35
|
+
end
|
metadata
ADDED
@@ -0,0 +1,247 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: slaver
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Denis Korobitcin
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-11-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
version_requirements: !ruby/object:Gem::Requirement
|
15
|
+
requirements:
|
16
|
+
- - ~>
|
17
|
+
- !ruby/object:Gem::Version
|
18
|
+
version: '3.1'
|
19
|
+
name: activerecord
|
20
|
+
requirement: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ~>
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: '3.1'
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
version_requirements: !ruby/object:Gem::Requirement
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '3.1'
|
33
|
+
name: activesupport
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
35
|
+
requirements:
|
36
|
+
- - ~>
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '3.1'
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
version_requirements: !ruby/object:Gem::Requirement
|
43
|
+
requirements:
|
44
|
+
- - '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
name: bundler
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
requirements:
|
50
|
+
- - '>='
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: '0'
|
53
|
+
type: :development
|
54
|
+
prerelease: false
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
name: rake
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
version_requirements: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ~>
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: '3.3'
|
75
|
+
name: rspec
|
76
|
+
requirement: !ruby/object:Gem::Requirement
|
77
|
+
requirements:
|
78
|
+
- - ~>
|
79
|
+
- !ruby/object:Gem::Version
|
80
|
+
version: '3.3'
|
81
|
+
type: :development
|
82
|
+
prerelease: false
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
version_requirements: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
name: rspec-rails
|
90
|
+
requirement: !ruby/object:Gem::Requirement
|
91
|
+
requirements:
|
92
|
+
- - '>='
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
version: '0'
|
95
|
+
type: :development
|
96
|
+
prerelease: false
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ~>
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0.5'
|
103
|
+
name: combustion
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ~>
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0.5'
|
109
|
+
type: :development
|
110
|
+
prerelease: false
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - '>='
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
name: appraisal
|
118
|
+
requirement: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
type: :development
|
124
|
+
prerelease: false
|
125
|
+
- !ruby/object:Gem::Dependency
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - '>='
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0'
|
131
|
+
name: pry-debugger
|
132
|
+
requirement: !ruby/object:Gem::Requirement
|
133
|
+
requirements:
|
134
|
+
- - '>='
|
135
|
+
- !ruby/object:Gem::Version
|
136
|
+
version: '0'
|
137
|
+
type: :development
|
138
|
+
prerelease: false
|
139
|
+
- !ruby/object:Gem::Dependency
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - <
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: 3.0.0
|
145
|
+
name: shoulda-matchers
|
146
|
+
requirement: !ruby/object:Gem::Requirement
|
147
|
+
requirements:
|
148
|
+
- - <
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
version: 3.0.0
|
151
|
+
type: :development
|
152
|
+
prerelease: false
|
153
|
+
- !ruby/object:Gem::Dependency
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - '>='
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
name: simplecov
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
requirements:
|
162
|
+
- - '>='
|
163
|
+
- !ruby/object:Gem::Version
|
164
|
+
version: '0'
|
165
|
+
type: :development
|
166
|
+
prerelease: false
|
167
|
+
- !ruby/object:Gem::Dependency
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - '>='
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
name: database_cleaner
|
174
|
+
requirement: !ruby/object:Gem::Requirement
|
175
|
+
requirements:
|
176
|
+
- - '>='
|
177
|
+
- !ruby/object:Gem::Version
|
178
|
+
version: '0'
|
179
|
+
type: :development
|
180
|
+
prerelease: false
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
version_requirements: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - '>='
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
name: sqlite3
|
188
|
+
requirement: !ruby/object:Gem::Requirement
|
189
|
+
requirements:
|
190
|
+
- - '>='
|
191
|
+
- !ruby/object:Gem::Version
|
192
|
+
version: '0'
|
193
|
+
type: :development
|
194
|
+
prerelease: false
|
195
|
+
description:
|
196
|
+
email:
|
197
|
+
- deniskorobitcin@gmail.com
|
198
|
+
executables: []
|
199
|
+
extensions: []
|
200
|
+
extra_rdoc_files: []
|
201
|
+
files:
|
202
|
+
- .gitignore
|
203
|
+
- .rspec
|
204
|
+
- Appraisals
|
205
|
+
- CHANGELOG.md
|
206
|
+
- Gemfile
|
207
|
+
- LICENSE.txt
|
208
|
+
- Makefile
|
209
|
+
- README.md
|
210
|
+
- Rakefile
|
211
|
+
- config.ru
|
212
|
+
- lib/slavable.rb
|
213
|
+
- lib/slaver.rb
|
214
|
+
- lib/slaver/config_handler.rb
|
215
|
+
- lib/slaver/connection.rb
|
216
|
+
- lib/slaver/pools_handler.rb
|
217
|
+
- lib/slaver/proxy.rb
|
218
|
+
- lib/slaver/proxy_methods.rb
|
219
|
+
- lib/slaver/railtie.rb
|
220
|
+
- lib/slaver/scope_proxy.rb
|
221
|
+
- lib/slaver/version.rb
|
222
|
+
- slaver.gemspec
|
223
|
+
homepage: https://github.com/abak-press/slaver
|
224
|
+
licenses:
|
225
|
+
- MIT
|
226
|
+
metadata: {}
|
227
|
+
post_install_message:
|
228
|
+
rdoc_options: []
|
229
|
+
require_paths:
|
230
|
+
- lib
|
231
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
232
|
+
requirements:
|
233
|
+
- - '>='
|
234
|
+
- !ruby/object:Gem::Version
|
235
|
+
version: '0'
|
236
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
237
|
+
requirements:
|
238
|
+
- - '>='
|
239
|
+
- !ruby/object:Gem::Version
|
240
|
+
version: '0'
|
241
|
+
requirements: []
|
242
|
+
rubyforge_project:
|
243
|
+
rubygems_version: 2.4.8
|
244
|
+
signing_key:
|
245
|
+
specification_version: 4
|
246
|
+
summary: Instant change of connection in rails application.
|
247
|
+
test_files: []
|