switch_connection 1.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3a610610ba7b802579bd70c8b25df8f8bba50299
4
+ data.tar.gz: c796e8855c8f3472629390723cd8c0c6c00559ea
5
+ SHA512:
6
+ metadata.gz: b3a4ad59a79b047914a09d125bae342993ab7b619cd48c23a2d7b0c53ade3be1d1d74948ae011a91741247b10729a611d5f1494e538945a641f196c9f4476958
7
+ data.tar.gz: 3d2fa748e38c0dc9536d9d41d0699868d387556df4d7730ba19e621a79a69e05d593f7b4810ed8e5f9d6dbdeb933fb4d4a0f765cb94b2025ceeaccc67543aca6
data/.gitignore ADDED
@@ -0,0 +1,26 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
23
+ vendor
24
+ /gemfiles/*.lock
25
+ .idea
26
+ .ruby-version
data/.hound.yml ADDED
@@ -0,0 +1,3 @@
1
+ ruby:
2
+ enabled: true
3
+ config_file: .rubocop.yml
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,63 @@
1
+ inherit_from: .rubocop_todo.yml
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.3
5
+ DisplayCopNames: true
6
+ Exclude:
7
+ - "gemfiles/**/*"
8
+ - "vendor/**/*"
9
+
10
+ Performance/RedundantBlockCall:
11
+ Enabled: false
12
+
13
+ Layout/AlignParameters:
14
+ Enabled: false
15
+
16
+ LineLength:
17
+ Max: 100
18
+
19
+ Metrics:
20
+ Enabled: false
21
+
22
+ Naming/FileName:
23
+ Exclude:
24
+ - Appraisals
25
+
26
+ Metrics/BlockLength:
27
+ Exclude:
28
+ - 'spec/**/*'
29
+
30
+ Style/AccessModifierDeclarations:
31
+ Enabled: false
32
+ Style/Alias:
33
+ EnforcedStyle: prefer_alias_method
34
+ Style/BlockDelimiters:
35
+ Enabled: false
36
+ Style/GuardClause:
37
+ Enabled: false
38
+ Style/HashSyntax:
39
+ Exclude:
40
+ - Rakefile
41
+ Style/IfUnlessModifier:
42
+ Enabled: false
43
+ Style/Lambda:
44
+ Enabled: false
45
+ Style/Next:
46
+ Enabled: false
47
+ Style/PercentLiteralDelimiters:
48
+ PreferredDelimiters:
49
+ '%w': '[]'
50
+ Style/RaiseArgs:
51
+ EnforcedStyle: compact
52
+ Style/SignalException:
53
+ Enabled: false
54
+ Style/TrailingCommaInArguments:
55
+ Enabled: false
56
+ Style/TrailingCommaInArrayLiteral:
57
+ Enabled: false
58
+ Style/TrailingCommaInHashLiteral:
59
+ Enabled: false
60
+ Style/FrozenStringLiteralComment:
61
+ Exclude:
62
+ - "gemfiles/*.gemfile"
63
+ - "Appraisals"
data/.rubocop_todo.yml ADDED
@@ -0,0 +1,2 @@
1
+ Style/Documentation:
2
+ Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.3.6
data/.travis.yml ADDED
@@ -0,0 +1,22 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.3.7
4
+ - 2.4.4
5
+ - 2.5.1
6
+ - ruby-head
7
+ gemfile:
8
+ - gemfiles/rails_3.2.gemfile
9
+ - gemfiles/rails_4.0.gemfile
10
+ - gemfiles/rails_4.1.gemfile
11
+ - gemfiles/rails_4.2.gemfile
12
+ - gemfiles/rails_5.0.gemfile
13
+ - gemfiles/rails_5.1.gemfile
14
+ - gemfiles/rails_5.2.gemfile
15
+ - gemfiles/rails_edge.gemfile
16
+ sudo: false
17
+ after_script:
18
+ - bundle exec rake benchmark
19
+ matrix:
20
+ allow_failures:
21
+ - rvm: ruby-head
22
+ - gemfile: gemfiles/rails_edge.gemfile
data/Appraisals ADDED
@@ -0,0 +1,66 @@
1
+ appraise 'rails-3.2' do
2
+ gem 'activerecord', '~> 3.2.0'
3
+
4
+ platforms :ruby do
5
+ gem 'sqlite3'
6
+ end
7
+ end
8
+
9
+ appraise 'rails-4.0' do
10
+ gem 'activerecord', '~> 4.0.0'
11
+
12
+ platforms :ruby do
13
+ gem 'sqlite3'
14
+ end
15
+ end
16
+
17
+ appraise 'rails-4.1' do
18
+ gem 'activerecord', '~> 4.1.0'
19
+
20
+ platforms :ruby do
21
+ gem 'sqlite3'
22
+ end
23
+ end
24
+
25
+ appraise 'rails-4.2' do
26
+ gem 'activerecord', '~> 4.2.0'
27
+
28
+ platforms :ruby do
29
+ gem 'sqlite3'
30
+ end
31
+ end
32
+
33
+ appraise 'rails-5.0' do
34
+ gem 'activerecord', '~> 5.0.0'
35
+
36
+ platforms :ruby do
37
+ gem 'sqlite3'
38
+ end
39
+ end
40
+
41
+ appraise 'rails-5.1' do
42
+ gem 'activerecord', '~> 5.1.0'
43
+
44
+ platforms :ruby do
45
+ gem 'sqlite3'
46
+ end
47
+ end
48
+
49
+ appraise 'rails-5.2' do
50
+ gem 'activerecord', '~> 5.2.0'
51
+
52
+ platforms :ruby do
53
+ gem 'sqlite3'
54
+ end
55
+ end
56
+
57
+ appraise 'rails-edge' do
58
+ gem 'activerecord', git: 'https://github.com/rails/rails'
59
+ gem 'arel', git: 'https://github.com/rails/arel'
60
+
61
+ platforms :ruby do
62
+ gem 'sqlite3'
63
+ end
64
+ end
65
+
66
+ # vim: set ft=ruby:
data/CHANGELOG.md ADDED
@@ -0,0 +1,73 @@
1
+ ## 1.0.0 (2019-07-31)
2
+ - Multi slaves support
3
+ - Connect to master by default
4
+ - Change switch point (thread safe)
5
+ - Log connection name
6
+
7
+ ## 0.8.0 (2016-06-06)
8
+ - Drop Ruby 2.0.0 and 2.1 support
9
+ - Add `AR::Base#with_readonly` and `AR::Base#with_writable`
10
+ - short-hand for `AR::Base.with_readonly` and `AR::Base.with_writable`
11
+ - Add `AR::Base#transaction_with`
12
+ - short-hand for `AR::Base.transaction_with`
13
+ - Fix warnings for Rails 5.0
14
+
15
+ ## 0.7.0 (2015-10-16)
16
+ - `Model.with_readonly` and `Model.with_writable` now raises error when the Model doesn't use switch_point
17
+
18
+ ## 0.6.0 (2015-04-14)
19
+ - Add `SwitchConnection::QueryCache` middleware
20
+ - `Model.cache` and `Model.uncached` is now hooked by switch_point
21
+ - `Model.cache` enables query cache for both readonly and writable.
22
+ - `Model.uncached` disables query cache for both readonly and writable.
23
+ - Add `SwitchConnection.with_readonly_all` and `SwitchConnection.with_writable_all` as shorthand
24
+
25
+ ## 0.5.0 (2014-11-05)
26
+ - Rename `SwitchConnection.with_connection` to `SwitchConnection.with_mode`
27
+ - To avoid confusion with `ActiveRecord::ConnectionPool#with_connection`
28
+ - Inherit superclass' switch_point configuration
29
+
30
+ ## 0.4.4 (2014-07-14)
31
+ - Memorize switch_point config to ConnectionSpecification#config instead of ConnectionPool
32
+ - To support multi-threaded environment since Rails 4.0.
33
+
34
+ ## 0.4.3 (2014-06-24)
35
+ - Add Model.transaction_with method (#2, @ryopeko)
36
+
37
+ ## 0.4.2 (2014-06-19)
38
+ - Establish connection lazily
39
+ - Just like ActiveRecord::Base, real connection isn't created until `.connection` is called
40
+
41
+ ## 0.4.1 (2014-06-19)
42
+ - Support :writable only configuration
43
+
44
+ ## 0.4.0 (2014-06-17)
45
+ - auto_writable is disabled by default
46
+ - To restore the previous behavior, set `config.auto_writable = true`.
47
+ - Add shorthand methods `SwitchConnection.with_readonly`, `SwitchConnection.with_writable`
48
+
49
+ ## 0.3.1 (2014-06-04)
50
+ - Support defaulting to writable ActiveRecord::Base connection
51
+ - When `:writable` key is omitted, ActiveRecord::Base is used for the writable connection.
52
+
53
+ ## 0.3.0 (2014-06-04)
54
+ - Improve thread safety
55
+ - Raise appropriate error if unknown mode is given to with_connection
56
+
57
+ ## 0.2.3 (2014-06-02)
58
+ - Support specifying the same database name within different switch_point
59
+ - Add Proxy#readonly? and Proxy#writable? predicate
60
+
61
+ ## 0.2.2 (2014-05-30)
62
+ - Fix nil error on with_{readonly,writable} from non-switch_point model
63
+
64
+ ## 0.2.1 (2014-05-29)
65
+ - Add Proxy#switch_name to switch proxy configuration
66
+ - Fix weird nil error when Config#define_switch_point isn't called yet
67
+
68
+ ## 0.2.0 (2014-05-29)
69
+ - Always send destructive operations to writable connection
70
+ - Fix bug on pooled connections
71
+
72
+ ## 0.1.0 (2014-05-28)
73
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in switch_point.gemspec
6
+ gemspec
7
+ gem 'sqlite3', '~> 1.3.6'
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Kohei Suzuki
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,143 @@
1
+ # SwitchConnection
2
+ [![Gem Version](https://badge.fury.io/rb/switch_point.svg)](http://badge.fury.io/rb/switch_point)
3
+ [![Build Status](https://travis-ci.org/phamvanhung2e123/switch_point.svg?branch=master)](https://travis-ci.org/phamvannhung22123/switch_point)
4
+ [![Coverage Status](https://img.shields.io/coveralls/phamvanhung2e123/switch_point.svg?branch=master)](https://coveralls.io/r/phamvannhung2e123/switch_point?branch=master)
5
+ [![Code Climate](https://codeclimate.com/github/phamvanhung2e123/switch_point/badges/gpa.svg)](https://codeclimate.com/github/phamvannhung2e123/switch_point)
6
+
7
+ Switching database connection between slave one and writable one. Fork from `switch_point` gem.
8
+ Original Version: https://github.com/eagletmt/switch_point.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ gem 'switch_connection'
15
+
16
+ And then execute:
17
+
18
+ $ bundle
19
+
20
+ Or install it yourself as:
21
+
22
+ $ gem install switch_connection
23
+
24
+ ## Usage
25
+ Suppose you have 4 databases: db-blog-master, db-blog-slave, db-comment-master and db-comment-slave.
26
+ Article model and Category model are stored in db-blog-{master,slave} and Comment model is stored in db-comment-{master,slave}.
27
+
28
+ ### Configuration
29
+ In database.yml:
30
+
31
+ ```yaml
32
+ production_blog_master:
33
+ adapter: mysql2
34
+ username: blog_writable
35
+ host: db-blog-master
36
+ production_blog_slave:
37
+ adapter: mysql2
38
+ username: blog_slave
39
+ host: db-blog-slave
40
+ production_comment_master:
41
+ ...
42
+ ```
43
+
44
+ In initializer:
45
+
46
+ ```ruby
47
+ SwitchConnection.configure do |config|
48
+ config.define_switch_point :blog,
49
+ slaves: [:"#{Rails.env}_blog_slave1",:"#{Rails.env}_blog_slave2"]
50
+ master: :"#{Rails.env}_blog_master"
51
+ config.define_switch_point :comment,
52
+ slaves: [:"#{Rails.env}_comment_slave"]
53
+ master: :"#{Rails.env}_comment_master"
54
+ end
55
+ ```
56
+
57
+ In models:
58
+
59
+ ```ruby
60
+ class Article < ActiveRecord::Base
61
+ use_switch_point :blog
62
+ end
63
+
64
+ class Category < ActiveRecord::Base
65
+ use_switch_point :blog
66
+ end
67
+
68
+ class Comment < ActiveRecord::Base
69
+ use_switch_point :comment
70
+ end
71
+ ```
72
+
73
+ ### Switching connections
74
+
75
+ ```ruby
76
+ Article.with_slave { Article.first } # Read from db-blog-slave
77
+ Category.with_slave { Category.first } # Also read from db-blog-slave
78
+ Comment.with_slave { Comment.first } # Read from db-comment-slave
79
+
80
+ Article.with_slave do
81
+ article = Article.first # Read from db-blog-slave
82
+ article.title = 'new title'
83
+ Article.with_master do
84
+ article.save! # Write to db-blog-master
85
+ article.reload # Read from db-blog-master
86
+ Category.first # Read from db-blog-master
87
+ end
88
+ end
89
+ ```
90
+
91
+ - with_switch_point
92
+ ```ruby
93
+ Book.with_switch_point(:main) { Book.count }
94
+ ```
95
+
96
+ Note that Article and Category shares their connections.
97
+
98
+ ## Notes
99
+
100
+ ### auto_master
101
+ `auto_master` by default.
102
+
103
+ When `auto_master` is enabled, destructive queries is sent to writable connection even in slave mode.
104
+ But it does NOT work well on transactions.
105
+
106
+ Suppose `after_save` callback is set to User model. When `User.create` is called, it proceeds as follows.
107
+
108
+ 1. BEGIN TRANSACTION is sent to READONLY connection.
109
+ 2. switch_point switches the connection to WRITABLE.
110
+ 3. INSERT statement is sent to WRITABLE connection.
111
+ 4. switch_point reset the connection to READONLY.
112
+ 5. after_save callback is called.
113
+ - At this point, the connection is READONLY and in a transaction.
114
+ 6. COMMIT TRANSACTION is sent to READONLY connection.
115
+
116
+ ### connection-related methods of model
117
+ Model has several connection-related methods: `connection_handler`, `connection_pool`, `connected?` and so on.
118
+ Since only `connection` method is monkey-patched, other connection-related methods doesn't work properly.
119
+ If you'd like to use those methods, send it to `Model.switch_point_proxy.model_for_connection`.
120
+
121
+ ## Internals
122
+ There's a proxy which holds two connections: slave one and writable one.
123
+ A proxy has a thread-local state indicating the current mode: slave or writable.
124
+
125
+ Each ActiveRecord model refers to a proxy.
126
+ `ActiveRecord::Base.connection` is hooked and delegated to the referred proxy.
127
+
128
+ When the writable connection is requested to execute destructive query, the slave connection clears its query cache.
129
+
130
+ ![switch_point](https://gyazo.wanko.cc/switch_point.svg)
131
+
132
+ ### Special case: ActiveRecord::Base.connection
133
+ Basically, each connection managed by a proxy isn't shared between proxies.
134
+ But there's one exception: ActiveRecord::Base.
135
+
136
+
137
+ ## Contributing
138
+
139
+ 1. Fork it ( https://github.com/phamvanmhung2e123/switch_point/fork )
140
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
141
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
142
+ 4. Push to the branch (`git push origin my-new-feature`)
143
+ 5. Create a new Pull Request