switch_point 0.1.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,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d470827ada389d47ee22e4956e6a45a42203abbb
4
+ data.tar.gz: 0b73cf90012e2fb62556830421c220cf01e59b21
5
+ SHA512:
6
+ metadata.gz: 62fde9258b6d872a319643c32935cbeda95bf2ce80c56f1ca96a73a2bf519562b51fbdf22feb870be8538418f4c273ec828d1ca2279d4678fb6977a701821cd0
7
+ data.tar.gz: 296199d722f3dc08deb552f7258796f2d124346cc1268af7302f209f255cb5f8c2ba27a6fcec4ecfffc44c0a6ed7b193768e2d48c03641c26be33fe00345fe3b
@@ -0,0 +1,22 @@
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
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,12 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.0.0
4
+ - 2.1.1
5
+ - ruby-head
6
+ gemfile:
7
+ - gemfiles/rails_3.2.gemfile
8
+ - gemfiles/rails_4.0.gemfile
9
+ - gemfiles/rails_4.1.gemfile
10
+ matrix:
11
+ allow_failures:
12
+ - rvm: ruby-head
@@ -0,0 +1,13 @@
1
+ appraise 'rails-3.2' do
2
+ gem 'activerecord', '~> 3.2'
3
+ end
4
+
5
+ appraise 'rails-4.0' do
6
+ gem 'activerecord', '~> 4.0'
7
+ end
8
+
9
+ appraise 'rails-4.1' do
10
+ gem 'activerecord', '~> 4.1'
11
+ end
12
+
13
+ # vim: set ft=ruby:
@@ -0,0 +1,2 @@
1
+ ## 0.1.0 (2014-05-28)
2
+ - Initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in switch_point.gemspec
4
+ gemspec
@@ -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.
@@ -0,0 +1,33 @@
1
+ # SwitchPoint
2
+ [![Build Status](https://travis-ci.org/eagletmt/switch_point.svg?branch=master)](https://travis-ci.org/eagletmt/switch_point)
3
+
4
+ Switching database connection between readonly one and writable one.
5
+
6
+ ## Installation
7
+
8
+ Add this line to your application's Gemfile:
9
+
10
+ gem 'switch_point'
11
+
12
+ And then execute:
13
+
14
+ $ bundle
15
+
16
+ Or install it yourself as:
17
+
18
+ $ gem install switch_point
19
+
20
+ ## Usage
21
+
22
+ See [spec/models](spec/models.rb).
23
+
24
+ ## TODO
25
+ - Thread safety
26
+
27
+ ## Contributing
28
+
29
+ 1. Fork it ( https://github.com/eagletmt/switch_point/fork )
30
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create a new Pull Request
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+
3
+ task :default => :spec
4
+
5
+ require 'rspec/core/rake_task'
6
+ RSpec::Core::RakeTask.new(:spec)
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 3.2"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 4.0"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,7 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "activerecord", "~> 4.1"
6
+
7
+ gemspec :path => "../"
@@ -0,0 +1,41 @@
1
+ require 'active_support/lazy_load_hooks'
2
+ require 'switch_point/config'
3
+ require 'switch_point/version'
4
+
5
+ module SwitchPoint
6
+ module ClassMethods
7
+ def configure(&block)
8
+ block.call(config)
9
+ end
10
+
11
+ def config
12
+ @config ||= Config.new
13
+ end
14
+
15
+ def readonly_all!
16
+ config.keys.each do |name|
17
+ readonly!(name)
18
+ end
19
+ end
20
+
21
+ def readonly!(name)
22
+ ProxyRepository.find(name).readonly!
23
+ end
24
+
25
+ def writable_all!
26
+ config.keys.each do |name|
27
+ writable!(name)
28
+ end
29
+ end
30
+
31
+ def writable!(name)
32
+ ProxyRepository.find(name).writable!
33
+ end
34
+ end
35
+ extend ClassMethods
36
+ end
37
+
38
+ ActiveSupport.on_load(:active_record) do
39
+ require 'switch_point/model'
40
+ ActiveRecord::Base.send(:include, SwitchPoint::Model)
41
+ end
@@ -0,0 +1,35 @@
1
+ module SwitchPoint
2
+ class Config
3
+ def define_switch_point(name, config)
4
+ assert_valid_config!(config)
5
+ @switch_points ||= {}
6
+ @switch_points[name] = config
7
+ end
8
+
9
+ def database_name(name, mode)
10
+ @switch_points[name][mode]
11
+ end
12
+
13
+ def model_name(name, mode)
14
+ "#{mode}_#{database_name(name, mode)}".camelize
15
+ end
16
+
17
+ def keys
18
+ @switch_points.keys
19
+ end
20
+
21
+ private
22
+
23
+ def assert_valid_config!(config)
24
+ [:readonly, :writable].each do |mode|
25
+ unless config.has_key?(mode)
26
+ raise ArgumentError.new("#{mode} key is required")
27
+ end
28
+ unless config[mode].is_a?(Symbol)
29
+ raise TypeError.new("#{mode}'s value must be Symbol")
30
+ end
31
+ end
32
+ nil
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,42 @@
1
+ require 'switch_point/proxy_repository'
2
+
3
+ module SwitchPoint
4
+ module Model
5
+ def self.included(model)
6
+ model.singleton_class.class_eval do
7
+ include ClassMethods
8
+ prepend ConnectionHook
9
+ end
10
+ end
11
+
12
+ module ConnectionHook
13
+ def connection
14
+ if @switch_point_name
15
+ switch_point_proxy.connection
16
+ else
17
+ super
18
+ end
19
+ end
20
+ end
21
+
22
+ module ClassMethods
23
+ def with_readonly(&block)
24
+ switch_point_proxy.with_readonly(&block)
25
+ end
26
+
27
+ def with_writable(&block)
28
+ switch_point_proxy.with_writable(&block)
29
+ end
30
+
31
+ private
32
+
33
+ def use_switch_point(name)
34
+ @switch_point_name = name
35
+ end
36
+
37
+ def switch_point_proxy
38
+ @switch_point_proxy ||= ProxyRepository.find(@switch_point_name)
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,55 @@
1
+ require 'switch_point/writable_connection_hook'
2
+
3
+ module SwitchPoint
4
+ class Proxy
5
+ def initialize(name)
6
+ @models = {}
7
+ [:readonly, :writable].each do |mode|
8
+ model = define_model(SwitchPoint.config.model_name(name, mode))
9
+ @models[mode] = model
10
+ model.establish_connection(SwitchPoint.config.database_name(name, mode))
11
+ memorize_switch_point_name(name, model.connection)
12
+ end
13
+ @models[:writable].connection.extend(WritableConnectionHook)
14
+ @mode = :readonly
15
+ end
16
+
17
+ def define_model(model_name)
18
+ model = Class.new(ActiveRecord::Base)
19
+ Proxy.const_set(model_name, model)
20
+ model
21
+ end
22
+
23
+ def memorize_switch_point_name(name, connection)
24
+ connection.instance_variable_set(:@switch_point_name, name)
25
+ end
26
+
27
+ def readonly!
28
+ @mode = :readonly
29
+ end
30
+
31
+ def writable!
32
+ @mode = :writable
33
+ end
34
+
35
+ def with_readonly(&block)
36
+ with_connection(:readonly, &block)
37
+ end
38
+
39
+ def with_writable(&block)
40
+ with_connection(:writable, &block)
41
+ end
42
+
43
+ def with_connection(mode, &block)
44
+ saved_mode = @mode
45
+ @mode = mode
46
+ block.call
47
+ ensure
48
+ @mode = saved_mode
49
+ end
50
+
51
+ def connection
52
+ @models[@mode].connection
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,20 @@
1
+ require 'singleton'
2
+ require 'switch_point/proxy'
3
+
4
+ module SwitchPoint
5
+ class ProxyRepository
6
+ include Singleton
7
+
8
+ def self.find(name)
9
+ instance.find(name)
10
+ end
11
+
12
+ def find(name)
13
+ proxies[name] ||= Proxy.new(name)
14
+ end
15
+
16
+ def proxies
17
+ @proxies ||= {}
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,3 @@
1
+ module SwitchPoint
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,17 @@
1
+ require 'switch_point/proxy_repository'
2
+
3
+ module SwitchPoint
4
+ # Propagate clear_query_cache in writable connection to readonly connection
5
+ module WritableConnectionHook
6
+ # See ActiveRecord::ConnectionAdapters::QueryCache
7
+ [:insert, :update, :delete].each do |method_name|
8
+ define_method(method_name) do |*args, &block|
9
+ proxy = ProxyRepository.find(@switch_point_name)
10
+ proxy.with_readonly do
11
+ proxy.connection.clear_query_cache
12
+ end
13
+ super(*args, &block)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,41 @@
1
+ SwitchPoint.configure do |config|
2
+ config.define_switch_point :main,
3
+ readonly: :main_readonly,
4
+ writable: :main_writable
5
+ config.define_switch_point :user,
6
+ readonly: :user,
7
+ writable: :user
8
+ config.define_switch_point :comment,
9
+ readonly: :comment_readonly,
10
+ writable: :comment_writable
11
+ end
12
+
13
+ class Book < ActiveRecord::Base
14
+ use_switch_point :main
15
+ end
16
+
17
+ class Publisher < ActiveRecord::Base
18
+ use_switch_point :main
19
+ end
20
+
21
+ class Comment < ActiveRecord::Base
22
+ use_switch_point :comment
23
+ end
24
+
25
+ class User < ActiveRecord::Base
26
+ use_switch_point :user
27
+ end
28
+
29
+ class Note < ActiveRecord::Base
30
+ end
31
+
32
+ base = { adapter: 'sqlite3' }
33
+ ActiveRecord::Base.configurations = {
34
+ 'main_readonly' => base.merge(database: 'main_readonly.sqlite3'),
35
+ 'main_writable' => base.merge(database: 'main_writable.sqlite3'),
36
+ 'user' => base.merge(database: 'user.sqlite3'),
37
+ 'comment_readonly' => base.merge(database: 'comment_readonly.sqlite3'),
38
+ 'comment_writable' => base.merge(database: 'comment_writable.sqlite3'),
39
+ 'default' => base.merge(database: 'default.sqlite3')
40
+ }
41
+ ActiveRecord::Base.establish_connection(:default)
@@ -0,0 +1,60 @@
1
+ require 'active_record'
2
+ require 'switch_point'
3
+ require 'models'
4
+
5
+ RSpec.configure do |config|
6
+ config.filter_run :focus
7
+ config.run_all_when_everything_filtered = true
8
+
9
+ if config.files_to_run.one?
10
+ config.full_backtrace = true
11
+ config.default_formatter = 'doc'
12
+ end
13
+
14
+ config.order = :random
15
+ Kernel.srand config.seed
16
+
17
+ config.expect_with :rspec do |expectations|
18
+ expectations.syntax = :expect
19
+ end
20
+
21
+ config.mock_with :rspec do |mocks|
22
+ mocks.syntax = :expect
23
+ mocks.verify_partial_doubles = true
24
+ end
25
+
26
+ config.before(:suite) do
27
+ sql = 'CREATE TABLE books (id integer primary key autoincrement)'
28
+ Book.connection.execute(sql)
29
+ Book.with_writable do
30
+ Book.connection.execute(sql)
31
+ end
32
+ end
33
+
34
+ config.after(:suite) do
35
+ ActiveRecord::Base.configurations.each_value do |config|
36
+ FileUtils.rm_f(config[:database])
37
+ end
38
+ end
39
+
40
+ config.after(:each) do
41
+ Book.delete_all
42
+ Book.with_writable do
43
+ Book.delete_all
44
+ end
45
+ end
46
+ end
47
+
48
+ RSpec::Matchers.define :connect_to do |expected|
49
+ database_name = lambda do |model|
50
+ model.connection.pool.spec.config[:database]
51
+ end
52
+
53
+ match do |actual|
54
+ database_name.call(actual) == expected
55
+ end
56
+
57
+ failure_message do |actual|
58
+ "expected #{actual.name} to connect to #{expected} but connected to #{database_name.call(actual)}"
59
+ end
60
+ end
@@ -0,0 +1,108 @@
1
+ RSpec.describe SwitchPoint::Model do
2
+ describe '.connection' do
3
+ it 'returns readonly connection by default' do
4
+ expect(Book).to connect_to('main_readonly.sqlite3')
5
+ expect(Publisher).to connect_to('main_readonly.sqlite3')
6
+ expect(User).to connect_to('user.sqlite3')
7
+ expect(Comment).to connect_to('comment_readonly.sqlite3')
8
+ expect(Note).to connect_to('default.sqlite3')
9
+ end
10
+
11
+ context 'without switch_point configuration' do
12
+ it 'returns default connection' do
13
+ expect(Note.connection).to equal(ActiveRecord::Base.connection)
14
+ end
15
+ end
16
+
17
+ context 'with the same switch point name' do
18
+ it 'shares connection' do
19
+ expect(Book.connection).to equal(Publisher.connection)
20
+ end
21
+ end
22
+ end
23
+
24
+ describe '.with_writable' do
25
+ it 'changes connection locally' do
26
+ Book.with_writable do
27
+ expect(Book).to connect_to('main_writable.sqlite3')
28
+ end
29
+ expect(Book).to connect_to('main_readonly.sqlite3')
30
+ end
31
+
32
+ it 'affects to other models with the same switch point' do
33
+ Book.with_writable do
34
+ expect(Publisher).to connect_to('main_writable.sqlite3')
35
+ end
36
+ expect(Publisher).to connect_to('main_readonly.sqlite3')
37
+ end
38
+
39
+ it 'does not affect to other models with different switch point' do
40
+ Book.with_writable do
41
+ expect(Comment).to connect_to('comment_readonly.sqlite3')
42
+ end
43
+ end
44
+
45
+ context 'with the same switch point' do
46
+ it 'shares connection' do
47
+ Book.with_writable do
48
+ expect(Book.connection).to equal(Publisher.connection)
49
+ end
50
+ end
51
+ end
52
+
53
+ context 'with query cache' do
54
+ context 'when writable connection does only non-destructive operation' do
55
+ it 'keeps readable query cache' do
56
+ # Ensure ActiveRecord::Base.connected? to make Book.cache work
57
+ # See ActiveRecord::QueryCache::ClassMethods#cache
58
+ ActiveRecord::Base.connection
59
+ Book.cache do
60
+ expect(Book.count).to eq(0)
61
+ expect(Book.connection.query_cache.size).to eq(1)
62
+ Book.with_writable do
63
+ Book.count
64
+ end
65
+ expect(Book.connection.query_cache.size).to eq(1)
66
+ end
67
+ end
68
+ end
69
+
70
+ context 'when writable connection does destructive operation' do
71
+ it 'clears readable query cache' do
72
+ # Ensure ActiveRecord::Base.connected? to make Book.cache work
73
+ # See ActiveRecord::QueryCache::ClassMethods#cache
74
+ ActiveRecord::Base.connection
75
+ Book.cache do
76
+ expect(Book.count).to eq(0)
77
+ expect(Book.connection.query_cache.size).to eq(1)
78
+ Book.with_writable do
79
+ Book.create
80
+ FileUtils.cp('main_writable.sqlite3', 'main_readonly.sqlite3') # XXX: emulate replication
81
+ end
82
+ expect(Book.connection.query_cache.size).to eq(0)
83
+ expect(Book.count).to eq(1)
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
89
+
90
+ describe '.with_readonly' do
91
+ context 'when writable! is called globally' do
92
+ before do
93
+ SwitchPoint.writable!(:main)
94
+ end
95
+
96
+ after do
97
+ SwitchPoint.readonly!(:main)
98
+ end
99
+
100
+ it 'locally overwrites global mode' do
101
+ Book.with_readonly do
102
+ expect(Book).to connect_to('main_readonly.sqlite3')
103
+ end
104
+ expect(Book).to connect_to('main_writable.sqlite3')
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,15 @@
1
+ RSpec.describe SwitchPoint do
2
+ describe '.writable!' do
3
+ after do
4
+ SwitchPoint.readonly!(:main)
5
+ end
6
+
7
+ it 'changes connection globally' do
8
+ expect(Book).to connect_to('main_readonly.sqlite3')
9
+ expect(Publisher).to connect_to('main_readonly.sqlite3')
10
+ SwitchPoint.writable!(:main)
11
+ expect(Book).to connect_to('main_writable.sqlite3')
12
+ expect(Publisher).to connect_to('main_writable.sqlite3')
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'switch_point/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "switch_point"
8
+ spec.version = SwitchPoint::VERSION
9
+ spec.authors = ["Kohei Suzuki"]
10
+ spec.email = ["eagletmt@gmail.com"]
11
+ spec.summary = %q{Switching database connection between readonly one and writable one.}
12
+ spec.description = %q{Switching database connection between readonly one and writable one.}
13
+ spec.homepage = "https://github.com/eagletmt/switch_point"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "appraisal"
22
+ spec.add_development_dependency "bundler"
23
+ spec.add_development_dependency "rake"
24
+ spec.add_development_dependency "rspec", "~> 3.0.0.rc1"
25
+ spec.add_development_dependency "sqlite3"
26
+ spec.add_dependency "activerecord", ">= 3.2.0"
27
+ end
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: switch_point
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kohei Suzuki
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-05-28 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: appraisal
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 3.0.0.rc1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 3.0.0.rc1
69
+ - !ruby/object:Gem::Dependency
70
+ name: sqlite3
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: activerecord
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: 3.2.0
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: 3.2.0
97
+ description: Switching database connection between readonly one and writable one.
98
+ email:
99
+ - eagletmt@gmail.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".travis.yml"
107
+ - Appraisals
108
+ - CHANGELOG.md
109
+ - Gemfile
110
+ - LICENSE.txt
111
+ - README.md
112
+ - Rakefile
113
+ - gemfiles/rails_3.2.gemfile
114
+ - gemfiles/rails_4.0.gemfile
115
+ - gemfiles/rails_4.1.gemfile
116
+ - lib/switch_point.rb
117
+ - lib/switch_point/config.rb
118
+ - lib/switch_point/model.rb
119
+ - lib/switch_point/proxy.rb
120
+ - lib/switch_point/proxy_repository.rb
121
+ - lib/switch_point/version.rb
122
+ - lib/switch_point/writable_connection_hook.rb
123
+ - spec/models.rb
124
+ - spec/spec_helper.rb
125
+ - spec/switch_point/model_spec.rb
126
+ - spec/switch_point_spec.rb
127
+ - switch_point.gemspec
128
+ homepage: https://github.com/eagletmt/switch_point
129
+ licenses:
130
+ - MIT
131
+ metadata: {}
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ requirements:
138
+ - - ">="
139
+ - !ruby/object:Gem::Version
140
+ version: '0'
141
+ required_rubygems_version: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ requirements: []
147
+ rubyforge_project:
148
+ rubygems_version: 2.2.2
149
+ signing_key:
150
+ specification_version: 4
151
+ summary: Switching database connection between readonly one and writable one.
152
+ test_files:
153
+ - spec/models.rb
154
+ - spec/spec_helper.rb
155
+ - spec/switch_point/model_spec.rb
156
+ - spec/switch_point_spec.rb