fresh_connection 0.4.0 → 0.4.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 755153c16ffcf02081f831ae593d7b15a23ea0d2
4
- data.tar.gz: 45145aa7be5d694975dfbc46330bd921d158d246
3
+ metadata.gz: a3ef49675ecb94116b2fb15051a79c6e85cb8b8b
4
+ data.tar.gz: 36c1f17b854cbe69105c665bdacf145d2d5262bc
5
5
  SHA512:
6
- metadata.gz: 8ed0b205aa9966468e9a39033b1726539d7bfc01acd66835f697f37739acc25369475b40163b5330e61cccf0abe26af388a8f32a6e072796a4f41739a163e993
7
- data.tar.gz: 89c830adfcc482727dea49d243e694d9d6e29ba4071eb6576c20dcafe7d0f76a19d8f6f45d2a021c7e616e36fa256e3ad6f449df3d8713c525fff7b963e7af20
6
+ metadata.gz: 8836051a97fd3274ca4be7b81b27137a6dbb35de688e006590bac32ef15220499de64151447a16a85fbc38b5bf7c1fb13fd75f3ba72e5b9c45d1926c85612efc
7
+ data.tar.gz: 639209d198f92ea1151ed15b9c5d756409e661c90c8c84c67414b259f2210f67f1bc776f950caf3304d89eb591de55851e9503ce6e597e54417e113fbfa58d8c
data/README.md CHANGED
@@ -37,7 +37,7 @@ If you want to access to the master server, use read_master.
37
37
  ```ruby
38
38
  Article.where(:id => 1).read_master
39
39
  ```
40
- It is possible to use readonly(false) instead of read_master, but it will be depricated at future version.
40
+ It is possible to use readonly(false) instead of read_master, but it is depricated.
41
41
 
42
42
  In transaction, All queries go to the master server.
43
43
 
@@ -148,6 +148,22 @@ AdminUser and Benefit access to ```admin_slave``` slave group.
148
148
  If a model that always access to the master server is exist, You write ```master_db_only!``` in the model.
149
149
  The model that master_db_only model's child is always access to master db.
150
150
 
151
+ ### for Unicorn
152
+
153
+ ```ruby
154
+ before_fork do |server, worker|
155
+ ...
156
+ ActiveRecord::Base.clear_all_slave_connections!
157
+ ...
158
+ end
159
+
160
+ after_fork do |server, worker|
161
+ ...
162
+ ActiveRecord::Base.establish_fresh_connection
163
+ ...
164
+ end
165
+ ```
166
+
151
167
  ### Slave Connection Manager
152
168
  Default slave connection manager is FreshConnection::ConnectionManager.
153
169
  If you would like to change slave connection manager, assign yourself slave connection manager.
@@ -192,7 +208,6 @@ First of all, you setting the config of the test mysql server in ```spec/databas
192
208
 
193
209
  ```bash
194
210
  bundle install --path .bundle
195
- GEM_HOME=.bundle/ruby/(your ruby version) gem install bundler --pre
196
211
  bundle exec appraisal install
197
212
  ```
198
213
 
@@ -8,17 +8,18 @@ Gem::Specification.new do |spec|
8
8
  spec.version = FreshConnection::VERSION
9
9
  spec.authors = ["Tsukasa OISHI"]
10
10
  spec.email = ["tsukasa.oishi@gmail.com"]
11
- spec.description = %q{https://github.com/tsukasaoishi/fresh_connection}
11
+
12
12
  spec.summary = %q{FreshConnection supports to connect with Mysql slave servers via Load Balancers.}
13
+ spec.description = %q{https://github.com/tsukasaoishi/fresh_connection}
13
14
  spec.homepage = "https://github.com/tsukasaoishi/fresh_connection"
14
15
  spec.license = "MIT"
15
16
 
16
- spec.files = `git ls-files`.split($/)
17
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = "exe"
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
19
20
  spec.require_paths = ["lib"]
20
- spec.required_ruby_version = '>= 2.0'
21
21
 
22
+ spec.required_ruby_version = '>= 2.0'
22
23
  spec.add_dependency 'activerecord', '>= 3.2.0', '< 4.3'
23
24
  spec.add_dependency 'activesupport', '>= 3.2.0', '< 4.3'
24
25
  spec.add_dependency 'mysql2', '~> 0.3'
@@ -26,5 +27,5 @@ Gem::Specification.new do |spec|
26
27
  spec.add_development_dependency "bundler", "~> 1.7"
27
28
  spec.add_development_dependency "rake", '~> 10.0'
28
29
  spec.add_development_dependency "rspec", '~> 3.0'
29
- spec.add_development_dependency 'appraisal', '~> 1.0'
30
+ spec.add_development_dependency 'appraisal', '~> 2.0'
30
31
  end
@@ -6,17 +6,24 @@ module FreshConnection
6
6
  "Can't connect to local MySQL server"
7
7
  ].map{|msg| Regexp.escape(msg)}.join("|")
8
8
 
9
+ private_constant :EXCEPTION_MESSAGE_WHEN_SLAVE_SERVER_DOWN
10
+
9
11
  attr_reader :slave_group
10
12
 
11
13
  def initialize(slave_group = "slave")
12
14
  @mutex = Mutex.new
13
- @slave_group = (slave_group.presence || "slave").to_s
15
+ @slave_group = slave_group.to_s
16
+ @slave_group = "slave" if @slave_group.empty?
14
17
  end
15
18
 
16
19
  def slave_connection
17
20
  end
18
21
  undef_method :slave_connection
19
22
 
23
+ def clear_all_connections!
24
+ end
25
+ undef_method :clear_all_connections!
26
+
20
27
  def put_aside!
21
28
  end
22
29
  undef_method :put_aside!
@@ -36,7 +43,7 @@ module FreshConnection
36
43
  end
37
44
 
38
45
  def slave_down_message?(message)
39
- /#{EXCEPTION_MESSAGE_WHEN_SLAVE_SERVER_DOWN}/o =~ message
46
+ /#{EXCEPTION_MESSAGE_WHEN_SLAVE_SERVER_DOWN}/o === message
40
47
  end
41
48
  end
42
49
  end
@@ -11,11 +11,11 @@ module FreshConnection
11
11
 
12
12
  def put_aside!
13
13
  synchronize do
14
- if c = slave_connections.delete(current_thread_id)
15
- c.disconnect! rescue nil
16
- end
14
+ slave_connections.values.each {|c| c.disconnect! rescue nil }
15
+ @slave_connections.clear
17
16
  end
18
17
  end
18
+ alias_method :clear_all_connections!, :put_aside!
19
19
 
20
20
  def recovery(failure_connection, exception)
21
21
  do_recovery = slave_down_message?(exception.message)
@@ -10,9 +10,10 @@ module FreshConnection
10
10
  base.slave_connection_handler = FreshConnection::SlaveConnectionHandler.new
11
11
  end
12
12
 
13
- if FreshConnection.rails_4?
13
+ case ActiveRecord::VERSION::MAJOR
14
+ when 4
14
15
  delegate :read_master, to: :all
15
- elsif FreshConnection.rails_3?
16
+ when 3
16
17
  delegate :read_master, to: :scoped
17
18
  end
18
19
 
@@ -32,6 +33,10 @@ module FreshConnection
32
33
  slave_connection_handler.connection(self)
33
34
  end
34
35
 
36
+ def clear_all_slave_connections!
37
+ slave_connection_handler.clear_all_connections!
38
+ end
39
+
35
40
  def master_db_only!
36
41
  @_fresh_connection_master_only = true
37
42
  end
@@ -41,7 +46,7 @@ module FreshConnection
41
46
  (self != ActiveRecord::Base && superclass.master_db_only?)
42
47
  end
43
48
 
44
- def put_aside!
49
+ def slave_connection_put_aside!
45
50
  slave_connection_handler.put_aside!
46
51
  end
47
52
 
@@ -0,0 +1,31 @@
1
+ module FreshConnection
2
+ module Extend
3
+ module ArRelation
4
+ module ForRails
5
+ def pluck(column_name)
6
+ if column_name.is_a?(Symbol) && column_names.include?(column_name.to_s)
7
+ column_name = "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}"
8
+ end
9
+
10
+ result = @klass.manage_access(enable_slave_access) do
11
+ klass.connection.select_all(select(column_name).arel, nil)
12
+ end
13
+
14
+ return result if result.nil? || result.empty?
15
+
16
+ last_columns = result.last.keys.last
17
+
18
+ result.map do |attributes|
19
+ klass.type_cast_attribute(last_columns, klass.initialize_attributes(attributes))
20
+ end
21
+ end
22
+
23
+ def read_master
24
+ relation = clone
25
+ relation.instance_variable_set("@read_from_master", true)
26
+ relation
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,20 @@
1
+ module FreshConnection
2
+ module Extend
3
+ module ArRelation
4
+ module ForRails
5
+ def pluck(*args)
6
+ @klass.manage_access(enable_slave_access) { super }
7
+ end
8
+
9
+ def read_master
10
+ spawn.read_master!
11
+ end
12
+
13
+ def read_master!
14
+ @read_from_master = true
15
+ self
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -1,17 +1,13 @@
1
1
  require 'active_support/deprecation'
2
+ require "fresh_connection/extend/ar_relation/for_rails#{ActiveRecord::VERSION::MAJOR}"
2
3
 
3
4
  module FreshConnection
4
5
  module Extend
5
6
  module ArRelation
6
7
  def self.prepended(base)
7
- if FreshConnection.rails_4?
8
- base.__send__(:prepend, ForRails4)
9
- elsif FreshConnection.rails_3?
10
- base.__send__(:prepend, ForRails3)
11
- end
8
+ base.__send__(:prepend, ForRails)
12
9
  end
13
10
 
14
-
15
11
  def calculate(operation, column_name, options = {})
16
12
  if options[:readonly] == false
17
13
  ActiveSupport::Deprecation.warn(":readonly key has been deprecated.", caller)
@@ -43,47 +39,6 @@ module FreshConnection
43
39
  super
44
40
  end
45
41
  end
46
-
47
- module ForRails4
48
- def pluck(*args)
49
- @klass.manage_access(enable_slave_access) { super }
50
- end
51
-
52
- def read_master
53
- spawn.read_master!
54
- end
55
-
56
- def read_master!
57
- @read_from_master = true
58
- self
59
- end
60
- end
61
-
62
- module ForRails3
63
- def pluck(column_name)
64
- if column_name.is_a?(Symbol) && column_names.include?(column_name.to_s)
65
- column_name = "#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(column_name)}"
66
- end
67
-
68
- result = @klass.manage_access(enable_slave_access) do
69
- klass.connection.select_all(select(column_name).arel, nil)
70
- end
71
-
72
- return result if result.nil? || result.empty?
73
-
74
- last_columns = result.last.keys.last
75
-
76
- result.map do |attributes|
77
- klass.type_cast_attribute(last_columns, klass.initialize_attributes(attributes))
78
- end
79
- end
80
-
81
- def read_master
82
- relation = clone
83
- relation.instance_variable_set("@read_from_master", true)
84
- relation
85
- end
86
- end
87
42
  end
88
43
  end
89
44
  end
@@ -1,10 +1,22 @@
1
1
  module FreshConnection
2
2
  module Rack
3
- class ConnectionManagement < ActiveRecord::ConnectionAdapters::ConnectionManagement
3
+ class ConnectionManagement
4
+ def initialize(app)
5
+ @app = app
6
+ end
7
+
4
8
  def call(env)
5
- super
6
- ensure
7
- ActiveRecord::Base.put_aside! unless env.key?("rack.test")
9
+ testing = env['rack.test']
10
+
11
+ response = @app.call(env)
12
+ response[2] = ::Rack::BodyProxy.new(response[2]) do
13
+ ActiveRecord::Base.slave_connection_put_aside! unless testing
14
+ end
15
+
16
+ response
17
+ rescue Exception
18
+ ActiveRecord::Base.slave_connection_put_aside! unless testing
19
+ raise
8
20
  end
9
21
  end
10
22
  end
@@ -3,12 +3,10 @@ require 'fresh_connection/rack/connection_management'
3
3
  module FreshConnection
4
4
  class Railtie < Rails::Railtie
5
5
  initializer "fresh_connection.configure_rails_initialization" do |app|
6
- ActiveSupport.on_load(:active_record) do
7
- app.config.app_middleware.swap(
8
- ActiveRecord::ConnectionAdapters::ConnectionManagement,
9
- FreshConnection::Rack::ConnectionManagement
10
- )
11
- end
6
+ app.config.app_middleware.insert_before(
7
+ ActiveRecord::ConnectionAdapters::ConnectionManagement,
8
+ FreshConnection::Rack::ConnectionManagement
9
+ )
12
10
  end
13
11
  end
14
12
  end
@@ -16,8 +16,14 @@ module FreshConnection
16
16
  detect_connection_manager(klass).slave_connection
17
17
  end
18
18
 
19
+ def clear_all_connections!
20
+ all_connection_managers do |connection_manager|
21
+ connection_manager.clear_all_connections!
22
+ end
23
+ end
24
+
19
25
  def put_aside!
20
- @class_to_pool.values.each do |connection_manager|
26
+ all_connection_managers do |connection_manager|
21
27
  connection_manager.put_aside!
22
28
  end
23
29
  end
@@ -32,6 +38,12 @@ module FreshConnection
32
38
 
33
39
  private
34
40
 
41
+ def all_connection_managers
42
+ @class_to_pool.values.each do |connection_manager|
43
+ yield(connection_manager)
44
+ end
45
+ end
46
+
35
47
  def detect_connection_manager(klass)
36
48
  c = @class_to_pool[klass.name]
37
49
  return c if c
@@ -1,4 +1,4 @@
1
1
  module FreshConnection
2
- VERSION = "0.4.0"
2
+ VERSION = "0.4.1"
3
3
  end
4
4
 
@@ -1,4 +1,3 @@
1
- require 'active_support/deprecation'
2
1
  require 'fresh_connection/connection_manager'
3
2
 
4
3
  module FreshConnection
@@ -8,24 +7,6 @@ module FreshConnection
8
7
  def connection_manager
9
8
  @connection_manager || ConnectionManager
10
9
  end
11
-
12
- def env=(e)
13
- ActiveSupport::Deprecation.warn("FreshConnection.env= has been deprecated.", caller)
14
- @env = e
15
- end
16
-
17
- def env
18
- ActiveSupport::Deprecation.warn("FreshConnection.env has been deprecated.", caller)
19
- @env || defined?(Rails) && Rails.env
20
- end
21
-
22
- def rails_3?
23
- ActiveRecord::VERSION::MAJOR == 3
24
- end
25
-
26
- def rails_4?
27
- ActiveRecord::VERSION::MAJOR == 4
28
- end
29
10
  end
30
11
  end
31
12
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fresh_connection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.0
4
+ version: 0.4.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tsukasa OISHI
8
8
  autorequire:
9
- bindir: bin
9
+ bindir: exe
10
10
  cert_chain: []
11
- date: 2015-05-07 00:00:00.000000000 Z
11
+ date: 2015-05-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -112,14 +112,14 @@ dependencies:
112
112
  requirements:
113
113
  - - "~>"
114
114
  - !ruby/object:Gem::Version
115
- version: '1.0'
115
+ version: '2.0'
116
116
  type: :development
117
117
  prerelease: false
118
118
  version_requirements: !ruby/object:Gem::Requirement
119
119
  requirements:
120
120
  - - "~>"
121
121
  - !ruby/object:Gem::Version
122
- version: '1.0'
122
+ version: '2.0'
123
123
  description: https://github.com/tsukasaoishi/fresh_connection
124
124
  email:
125
125
  - tsukasa.oishi@gmail.com
@@ -147,6 +147,8 @@ files:
147
147
  - lib/fresh_connection/extend.rb
148
148
  - lib/fresh_connection/extend/ar_base.rb
149
149
  - lib/fresh_connection/extend/ar_relation.rb
150
+ - lib/fresh_connection/extend/ar_relation/for_rails3.rb
151
+ - lib/fresh_connection/extend/ar_relation/for_rails4.rb
150
152
  - lib/fresh_connection/extend/ar_statement_cache.rb
151
153
  - lib/fresh_connection/extend/connection_handler.rb
152
154
  - lib/fresh_connection/extend/mysql2_adapter.rb
@@ -155,15 +157,6 @@ files:
155
157
  - lib/fresh_connection/slave_connection_handler.rb
156
158
  - lib/fresh_connection/version.rb
157
159
  - log/.gitkeep
158
- - spec/database.yml
159
- - spec/db_schema.sql
160
- - spec/prepare.rb
161
- - spec/spec_helper.rb
162
- - spec/support/active_record_logger.rb
163
- - spec/unit/access_control_spec.rb
164
- - spec/unit/ar_base_spec.rb
165
- - spec/unit/fresh_connection_spec.rb
166
- - spec/unit/recovery_spec.rb
167
160
  homepage: https://github.com/tsukasaoishi/fresh_connection
168
161
  licenses:
169
162
  - MIT
@@ -188,13 +181,4 @@ rubygems_version: 2.4.5
188
181
  signing_key:
189
182
  specification_version: 4
190
183
  summary: FreshConnection supports to connect with Mysql slave servers via Load Balancers.
191
- test_files:
192
- - spec/database.yml
193
- - spec/db_schema.sql
194
- - spec/prepare.rb
195
- - spec/spec_helper.rb
196
- - spec/support/active_record_logger.rb
197
- - spec/unit/access_control_spec.rb
198
- - spec/unit/ar_base_spec.rb
199
- - spec/unit/fresh_connection_spec.rb
200
- - spec/unit/recovery_spec.rb
184
+ test_files: []
data/spec/database.yml DELETED
@@ -1,14 +0,0 @@
1
- test:
2
- adapter: mysql2
3
- encoding: utf8
4
- database: fresh_connection_test_master
5
- pool: 5
6
- username: root
7
- password:
8
-
9
- slave1:
10
- database: fresh_connection_test_slave1
11
-
12
- slave2:
13
- database: fresh_connection_test_slave2
14
-
data/spec/db_schema.sql DELETED
@@ -1,296 +0,0 @@
1
- -- MySQL dump 10.13 Distrib 5.6.15, for osx10.9 (x86_64)
2
- --
3
- -- Host: localhost Database: fresh_connection_test_master
4
- -- ------------------------------------------------------
5
- -- Server version 5.6.15
6
-
7
- /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
8
- /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
9
- /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
10
- /*!40101 SET NAMES utf8 */;
11
- /*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
12
- /*!40103 SET TIME_ZONE='+00:00' */;
13
- /*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
14
- /*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
15
- /*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
16
- /*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
17
-
18
- --
19
- -- Current Database: `fresh_connection_test_master`
20
- --
21
-
22
- CREATE DATABASE /*!32312 IF NOT EXISTS*/ `fresh_connection_test_master` /*!40100 DEFAULT CHARACTER SET utf8 */;
23
-
24
- USE `fresh_connection_test_master`;
25
-
26
- --
27
- -- Table structure for table `addresses`
28
- --
29
-
30
- DROP TABLE IF EXISTS `addresses`;
31
- /*!40101 SET @saved_cs_client = @@character_set_client */;
32
- /*!40101 SET character_set_client = utf8 */;
33
- CREATE TABLE `addresses` (
34
- `id` int(11) NOT NULL AUTO_INCREMENT,
35
- `user_id` int(11) NOT NULL DEFAULT '0',
36
- `prefecture` varchar(255) NOT NULL DEFAULT '',
37
- `created_at` datetime DEFAULT NULL,
38
- `updated_at` datetime DEFAULT NULL,
39
- PRIMARY KEY (`id`)
40
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
41
- /*!40101 SET character_set_client = @saved_cs_client */;
42
-
43
- --
44
- -- Dumping data for table `addresses`
45
- --
46
-
47
- LOCK TABLES `addresses` WRITE;
48
- /*!40000 ALTER TABLE `addresses` DISABLE KEYS */;
49
- INSERT INTO `addresses` VALUES (1,1,'Tokyo (master)','2014-04-10 07:24:16','2014-04-10 07:24:16');
50
- /*!40000 ALTER TABLE `addresses` ENABLE KEYS */;
51
- UNLOCK TABLES;
52
-
53
- --
54
- -- Table structure for table `tels`
55
- --
56
-
57
- DROP TABLE IF EXISTS `tels`;
58
- /*!40101 SET @saved_cs_client = @@character_set_client */;
59
- /*!40101 SET character_set_client = utf8 */;
60
- CREATE TABLE `tels` (
61
- `id` int(11) NOT NULL AUTO_INCREMENT,
62
- `user_id` int(11) NOT NULL DEFAULT '0',
63
- `number` varchar(255) NOT NULL DEFAULT '',
64
- `created_at` datetime DEFAULT NULL,
65
- `updated_at` datetime DEFAULT NULL,
66
- PRIMARY KEY (`id`)
67
- ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
68
- /*!40101 SET character_set_client = @saved_cs_client */;
69
-
70
- --
71
- -- Dumping data for table `tels`
72
- --
73
-
74
- LOCK TABLES `tels` WRITE;
75
- /*!40000 ALTER TABLE `tels` DISABLE KEYS */;
76
- INSERT INTO `tels` VALUES (1,1,'03-1111-1111 (master)','2014-04-10 07:24:16','2014-04-10 07:24:16'),(2,1,'03-1111-1112 (master)','2014-04-10 07:24:16','2014-04-10 07:24:16'),(3,1,'03-1111-1113 (master)','2014-04-10 07:24:16','2014-04-10 07:24:16');
77
- /*!40000 ALTER TABLE `tels` ENABLE KEYS */;
78
- UNLOCK TABLES;
79
-
80
- --
81
- -- Table structure for table `users`
82
- --
83
-
84
- DROP TABLE IF EXISTS `users`;
85
- /*!40101 SET @saved_cs_client = @@character_set_client */;
86
- /*!40101 SET character_set_client = utf8 */;
87
- CREATE TABLE `users` (
88
- `id` int(11) NOT NULL AUTO_INCREMENT,
89
- `name` varchar(255) NOT NULL DEFAULT '',
90
- `created_at` datetime DEFAULT NULL,
91
- `updated_at` datetime DEFAULT NULL,
92
- PRIMARY KEY (`id`)
93
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
94
- /*!40101 SET character_set_client = @saved_cs_client */;
95
-
96
- --
97
- -- Dumping data for table `users`
98
- --
99
-
100
- LOCK TABLES `users` WRITE;
101
- /*!40000 ALTER TABLE `users` DISABLE KEYS */;
102
- INSERT INTO `users` VALUES (1,'Tsukasa (master)','2014-04-10 07:24:16','2014-04-10 07:24:16');
103
- INSERT INTO `users` VALUES (2,'Other','2015-01-16 07:24:16','2014-04-10 07:24:16');
104
- /*!40000 ALTER TABLE `users` ENABLE KEYS */;
105
- UNLOCK TABLES;
106
-
107
- --
108
- -- Current Database: `fresh_connection_test_slave1`
109
- --
110
-
111
- CREATE DATABASE /*!32312 IF NOT EXISTS*/ `fresh_connection_test_slave1` /*!40100 DEFAULT CHARACTER SET utf8 */;
112
-
113
- USE `fresh_connection_test_slave1`;
114
-
115
- --
116
- -- Table structure for table `addresses`
117
- --
118
-
119
- DROP TABLE IF EXISTS `addresses`;
120
- /*!40101 SET @saved_cs_client = @@character_set_client */;
121
- /*!40101 SET character_set_client = utf8 */;
122
- CREATE TABLE `addresses` (
123
- `id` int(11) NOT NULL AUTO_INCREMENT,
124
- `user_id` int(11) NOT NULL DEFAULT '0',
125
- `prefecture` varchar(255) NOT NULL DEFAULT '',
126
- `created_at` datetime DEFAULT NULL,
127
- `updated_at` datetime DEFAULT NULL,
128
- PRIMARY KEY (`id`)
129
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
130
- /*!40101 SET character_set_client = @saved_cs_client */;
131
-
132
- --
133
- -- Dumping data for table `addresses`
134
- --
135
-
136
- LOCK TABLES `addresses` WRITE;
137
- /*!40000 ALTER TABLE `addresses` DISABLE KEYS */;
138
- INSERT INTO `addresses` VALUES (1,1,'Tokyo (slave1)','2014-04-10 07:24:16','2014-04-10 07:24:16');
139
- /*!40000 ALTER TABLE `addresses` ENABLE KEYS */;
140
- UNLOCK TABLES;
141
-
142
- --
143
- -- Table structure for table `tels`
144
- --
145
-
146
- DROP TABLE IF EXISTS `tels`;
147
- /*!40101 SET @saved_cs_client = @@character_set_client */;
148
- /*!40101 SET character_set_client = utf8 */;
149
- CREATE TABLE `tels` (
150
- `id` int(11) NOT NULL AUTO_INCREMENT,
151
- `user_id` int(11) NOT NULL DEFAULT '0',
152
- `number` varchar(255) NOT NULL DEFAULT '',
153
- `created_at` datetime DEFAULT NULL,
154
- `updated_at` datetime DEFAULT NULL,
155
- PRIMARY KEY (`id`)
156
- ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
157
- /*!40101 SET character_set_client = @saved_cs_client */;
158
-
159
- --
160
- -- Dumping data for table `tels`
161
- --
162
-
163
- LOCK TABLES `tels` WRITE;
164
- /*!40000 ALTER TABLE `tels` DISABLE KEYS */;
165
- INSERT INTO `tels` VALUES (1,1,'03-1111-1111 (slave1)','2014-04-10 07:24:16','2014-04-10 07:24:16'),(2,1,'03-1111-1112 (slave1)','2014-04-10 07:24:16','2014-04-10 07:24:16'),(3,1,'03-1111-1113 (slave1)','2014-04-10 07:24:16','2014-04-10 07:24:16');
166
- /*!40000 ALTER TABLE `tels` ENABLE KEYS */;
167
- UNLOCK TABLES;
168
-
169
- --
170
- -- Table structure for table `users`
171
- --
172
-
173
- DROP TABLE IF EXISTS `users`;
174
- /*!40101 SET @saved_cs_client = @@character_set_client */;
175
- /*!40101 SET character_set_client = utf8 */;
176
- CREATE TABLE `users` (
177
- `id` int(11) NOT NULL AUTO_INCREMENT,
178
- `name` varchar(255) NOT NULL DEFAULT '',
179
- `created_at` datetime DEFAULT NULL,
180
- `updated_at` datetime DEFAULT NULL,
181
- PRIMARY KEY (`id`)
182
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
183
- /*!40101 SET character_set_client = @saved_cs_client */;
184
-
185
- --
186
- -- Dumping data for table `users`
187
- --
188
-
189
- LOCK TABLES `users` WRITE;
190
- /*!40000 ALTER TABLE `users` DISABLE KEYS */;
191
- INSERT INTO `users` VALUES (1,'Tsukasa (slave1)','2014-04-10 07:24:16','2014-04-10 07:24:16');
192
- INSERT INTO `users` VALUES (2,'Other','2015-01-16 07:24:16','2014-04-10 07:24:16');
193
- INSERT INTO `users` VALUES (3,'Other','2015-01-16 07:24:16','2014-04-10 07:24:16');
194
- /*!40000 ALTER TABLE `users` ENABLE KEYS */;
195
- UNLOCK TABLES;
196
-
197
- --
198
- -- Current Database: `fresh_connection_test_slave2`
199
- --
200
-
201
- CREATE DATABASE /*!32312 IF NOT EXISTS*/ `fresh_connection_test_slave2` /*!40100 DEFAULT CHARACTER SET utf8 */;
202
-
203
- USE `fresh_connection_test_slave2`;
204
-
205
- --
206
- -- Table structure for table `addresses`
207
- --
208
-
209
- DROP TABLE IF EXISTS `addresses`;
210
- /*!40101 SET @saved_cs_client = @@character_set_client */;
211
- /*!40101 SET character_set_client = utf8 */;
212
- CREATE TABLE `addresses` (
213
- `id` int(11) NOT NULL AUTO_INCREMENT,
214
- `user_id` int(11) NOT NULL DEFAULT '0',
215
- `prefecture` varchar(255) NOT NULL DEFAULT '',
216
- `created_at` datetime DEFAULT NULL,
217
- `updated_at` datetime DEFAULT NULL,
218
- PRIMARY KEY (`id`)
219
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
220
- /*!40101 SET character_set_client = @saved_cs_client */;
221
-
222
- --
223
- -- Dumping data for table `addresses`
224
- --
225
-
226
- LOCK TABLES `addresses` WRITE;
227
- /*!40000 ALTER TABLE `addresses` DISABLE KEYS */;
228
- INSERT INTO `addresses` VALUES (1,1,'Tokyo (slave2)','2014-04-10 07:24:16','2014-04-10 07:24:16');
229
- /*!40000 ALTER TABLE `addresses` ENABLE KEYS */;
230
- UNLOCK TABLES;
231
-
232
- --
233
- -- Table structure for table `tels`
234
- --
235
-
236
- DROP TABLE IF EXISTS `tels`;
237
- /*!40101 SET @saved_cs_client = @@character_set_client */;
238
- /*!40101 SET character_set_client = utf8 */;
239
- CREATE TABLE `tels` (
240
- `id` int(11) NOT NULL AUTO_INCREMENT,
241
- `user_id` int(11) NOT NULL DEFAULT '0',
242
- `number` varchar(255) NOT NULL DEFAULT '',
243
- `created_at` datetime DEFAULT NULL,
244
- `updated_at` datetime DEFAULT NULL,
245
- PRIMARY KEY (`id`)
246
- ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
247
- /*!40101 SET character_set_client = @saved_cs_client */;
248
-
249
- --
250
- -- Dumping data for table `tels`
251
- --
252
-
253
- LOCK TABLES `tels` WRITE;
254
- /*!40000 ALTER TABLE `tels` DISABLE KEYS */;
255
- INSERT INTO `tels` VALUES (1,1,'03-1111-1111 (slave2)','2014-04-10 07:24:16','2014-04-10 07:24:16'),(2,1,'03-1111-1112 (slave2)','2014-04-10 07:24:16','2014-04-10 07:24:16'),(3,1,'03-1111-1113 (slave2)','2014-04-10 07:24:16','2014-04-10 07:24:16');
256
- /*!40000 ALTER TABLE `tels` ENABLE KEYS */;
257
- UNLOCK TABLES;
258
-
259
- --
260
- -- Table structure for table `users`
261
- --
262
-
263
- DROP TABLE IF EXISTS `users`;
264
- /*!40101 SET @saved_cs_client = @@character_set_client */;
265
- /*!40101 SET character_set_client = utf8 */;
266
- CREATE TABLE `users` (
267
- `id` int(11) NOT NULL AUTO_INCREMENT,
268
- `name` varchar(255) NOT NULL DEFAULT '',
269
- `created_at` datetime DEFAULT NULL,
270
- `updated_at` datetime DEFAULT NULL,
271
- PRIMARY KEY (`id`)
272
- ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
273
- /*!40101 SET character_set_client = @saved_cs_client */;
274
-
275
- --
276
- -- Dumping data for table `users`
277
- --
278
-
279
- LOCK TABLES `users` WRITE;
280
- /*!40000 ALTER TABLE `users` DISABLE KEYS */;
281
- INSERT INTO `users` VALUES (1,'Tsukasa (slave2)','2014-04-10 07:24:16','2014-04-10 07:24:16');
282
- INSERT INTO `users` VALUES (2,'Other','2015-01-16 07:24:16','2014-04-10 07:24:16');
283
- INSERT INTO `users` VALUES (3,'Other','2015-01-16 07:24:16','2014-04-10 07:24:16');
284
- /*!40000 ALTER TABLE `users` ENABLE KEYS */;
285
- UNLOCK TABLES;
286
- /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
287
-
288
- /*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
289
- /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
290
- /*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
291
- /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
292
- /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
293
- /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
294
- /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
295
-
296
- -- Dump completed on 2014-04-10 21:36:33
data/spec/prepare.rb DELETED
@@ -1,35 +0,0 @@
1
- require 'yaml'
2
- require 'active_record'
3
- require 'fresh_connection'
4
-
5
- system("mysql -uroot < spec/db_schema.sql")
6
-
7
- module ActiveRecord
8
- class Base
9
- self.configurations = YAML.load_file(File.join(File.dirname(__FILE__), "database.yml"))
10
- establish_connection(configurations["test"])
11
- establish_fresh_connection :slave1
12
- end
13
- end
14
-
15
- class Parent < ActiveRecord::Base
16
- self.abstract_class = true
17
- end
18
-
19
- class Slave2 < ActiveRecord::Base
20
- self.abstract_class = true
21
- establish_fresh_connection :slave2
22
- end
23
-
24
- class User < ActiveRecord::Base
25
- has_one :address
26
- has_many :tels
27
- end
28
-
29
- class Address < ActiveRecord::Base
30
- belongs_to :user
31
- end
32
-
33
- class Tel < Slave2
34
- belongs_to :user
35
- end
data/spec/spec_helper.rb DELETED
@@ -1,7 +0,0 @@
1
- ENV["RAILS_ENV"]="test"
2
- $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
3
- require 'fresh_connection'
4
-
5
- require File.join(File.dirname(__FILE__), "prepare.rb")
6
-
7
- Dir[File.join(File.dirname(__FILE__), "/support/**/*.rb")].each {|f| require f}
@@ -1,3 +0,0 @@
1
- require 'logger'
2
-
3
- ActiveRecord::Base.logger = Logger.new(File.join(File.dirname(__FILE__), '../../log/sql.log'))
@@ -1,63 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe FreshConnection::AccessControl do
4
- before(:each) do
5
- @ac = FreshConnection::AccessControl
6
- end
7
-
8
- context ".access" do
9
- it "persisted first state(slave)" do
10
- ret = []
11
- @ac.access(true) do
12
- @ac.access(true) do
13
- ret << @ac.slave_access?
14
- @ac.access(false) do
15
- ret << @ac.slave_access?
16
- end
17
- end
18
- end
19
-
20
- expect(ret).to be_all{|item| item}
21
- end
22
-
23
- it "persisted first state(master)" do
24
- ret = []
25
- @ac.access(false) do
26
- @ac.access(true) do
27
- ret << @ac.slave_access?
28
- @ac.access(false) do
29
- ret << @ac.slave_access?
30
- end
31
- end
32
- end
33
-
34
- expect(ret).to_not be_all{|item| item}
35
- end
36
-
37
- it "outside is always master" do
38
- ret = []
39
- ret << @ac.slave_access?
40
- @ac.access(true){}
41
- ret << @ac.slave_access?
42
-
43
- expect(ret).to_not be_all{|item| item}
44
- end
45
- end
46
-
47
- context ".force_master_access" do
48
- it "forced master state" do
49
- @ac.access(true) do
50
- @ac.force_master_access do
51
- expect(@ac.slave_access?).to be_falsey
52
- end
53
- end
54
- end
55
-
56
- it "not effect outside" do
57
- @ac.access(true) do
58
- @ac.force_master_access {}
59
- expect(@ac.slave_access?).to be_truthy
60
- end
61
- end
62
- end
63
- end
@@ -1,42 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe ActiveRecord::Base do
4
- context ".slave_connection" do
5
- it "return Mysql2Adapter object" do
6
- expect(User.slave_connection).to be_a(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
7
- end
8
- end
9
-
10
- context ".slave_group" do
11
- class Tel2 < Slave2
12
- self.table_name = :tel
13
- end
14
-
15
- it "equal group_name of establish_fresh_connection" do
16
- expect(User.slave_group).to eq("slave1")
17
- expect(Tel.slave_group).to eq("slave2")
18
- end
19
-
20
- it "equal 'slave' when not specific group_name" do
21
- Tel2.establish_fresh_connection
22
- expect(Tel2.slave_group).to eq("slave")
23
- end
24
- end
25
-
26
- context ".master_db_only?" do
27
- class User2 < Parent
28
- self.table_name = :users
29
- end
30
-
31
- it "childrend of master_db_only class is master_db_only" do
32
- expect(User2.master_db_only?).to be_falsey
33
- Parent.master_db_only!
34
- expect(User2.master_db_only?).to be_truthy
35
- end
36
-
37
- it "not effect other class" do
38
- Parent.master_db_only!
39
- expect(Address.master_db_only?).to be_falsey
40
- end
41
- end
42
- end
@@ -1,141 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe FreshConnection do
4
- before(:each) do
5
- @user = User.where(id: 1).first
6
- end
7
-
8
- context "access to slave" do
9
- it "select from User is to access to slave1" do
10
- data = [
11
- @user.name,
12
- Address.first.user.name,
13
- Tel.first.user.name,
14
- ]
15
-
16
- expect(data).to be_all{|n| n.include?("slave1")}
17
- end
18
-
19
- it "select from Address is to access to slave1" do
20
- data = [
21
- Address.first.prefecture,
22
- @user.address.prefecture
23
- ]
24
-
25
- expect(data).to be_all{|n| n.include?("slave1")}
26
- end
27
-
28
- it "select from Address is to access to slave2" do
29
- data = [
30
- Tel.first.number,
31
- @user.tels.first.number
32
- ]
33
-
34
- expect(data).to be_all{|n| n.include?("slave2")}
35
- end
36
-
37
- it "select with join is to access to slave1" do
38
- name = User.joins(:address).where("addresses.user_id = 1").where(id: 1).first.name
39
- expect(name).to be_include("slave1")
40
- end
41
-
42
- it "pluck is access to slave1" do
43
- expect(User.where(id: 1).pluck(:name).first).to be_include("slave")
44
- end
45
-
46
- it "pluck returns empty array when result of condition is empty" do
47
- expect(User.limit(0).pluck(:name)).to be_empty
48
- end
49
-
50
- it "count is access to slave" do
51
- expect(User.where(name: "Other").count).to eq(2)
52
- end
53
- end
54
-
55
- context "access to master" do
56
- it "in transaction" do
57
- User.transaction do
58
- expect(@user.name).to be_include("slave1")
59
- data = [
60
- Address.first.user.name,
61
- Address.first.prefecture,
62
- Tel.first.number,
63
- Tel.first.user.name,
64
- @user.address.prefecture,
65
- @user.tels.first.number,
66
- User.joins(:address).where(id: 1).where("addresses.user_id = 1").first.name,
67
- User.where(id: 1).pluck(:name).first
68
- ]
69
- expect(data).to be_all{|n| n.include?("master")}
70
-
71
- expect(User.where(name: "Other").count).to eq(1)
72
- end
73
- end
74
-
75
- it "specify read_master" do
76
- data = [
77
- Address.read_master.first.prefecture,
78
- Address.includes(:user).read_master.first.user.name,
79
- Tel.read_master.first.number,
80
- Tel.includes(:user).read_master.first.user.name,
81
- @user.tels.read_master.first.number,
82
- User.where(id: 1).includes(:tels).read_master.first.tels.first.number,
83
- User.where(id: 1).includes(:address).read_master.first.address.prefecture,
84
- User.where(id: 1).joins(:address).where("addresses.user_id = 1").read_master.first.name,
85
- User.where(id: 1).read_master.pluck(:name).first
86
- ]
87
-
88
- expect(data).to be_all{|n| n.include?("master")}
89
- expect(User.where(name: "Other").read_master.count).to eq(1)
90
- end
91
-
92
- it "specify readonly(false)" do
93
- ActiveSupport::Deprecation.silence do
94
- data = [
95
- Address.readonly(false).first.prefecture,
96
- Address.includes(:user).readonly(false).first.user.name,
97
- Tel.readonly(false).first.number,
98
- Tel.includes(:user).readonly(false).first.user.name,
99
- @user.tels.readonly(false).first.number,
100
- User.where(id: 1).includes(:tels).readonly(false).first.tels.first.number,
101
- User.where(id: 1).includes(:address).readonly(false).first.address.prefecture,
102
- User.where(id: 1).joins(:address).where("addresses.user_id = 1").readonly(false).first.name,
103
- User.where(id: 1).readonly(false).pluck(:name).first
104
- ]
105
-
106
- expect(data).to be_all{|n| n.include?("master")}
107
- expect(User.where(name: "Other").readonly(false).count).to eq(1)
108
- expect(User.where(name: "Other").count(:readonly => false)).to eq(1)
109
- end
110
- end
111
- end
112
-
113
- context "master_db_only model always access to master" do
114
- class Address3 < ActiveRecord::Base
115
- self.table_name = "addresses"
116
- master_db_only!
117
- end
118
-
119
- class Master < ActiveRecord::Base
120
- self.abstract_class = true
121
- master_db_only!
122
- end
123
-
124
- class Tel3 < Master
125
- self.table_name = "tels"
126
- end
127
-
128
- it "self is master_db_only model" do
129
- expect(Address3.first.prefecture).to be_include("master")
130
- end
131
-
132
- it "parent is master_db_only model" do
133
- expect(Tel3.first.number).to be_include("master")
134
- end
135
-
136
- it "not effect other models" do
137
- expect(Address.first.prefecture).to be_include("slave1")
138
- expect(Tel.first.number).to be_include("slave2")
139
- end
140
- end
141
- end
@@ -1,39 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "recovery when Mysql down" do
4
- class User3 < ActiveRecord::Base
5
- self.table_name = "users"
6
-
7
- class << self
8
- attr_writer :limit_time
9
-
10
- def slave_connection
11
- @access_time ||= 0
12
- @access_time += 1
13
- if @access_time > limit_time
14
- super
15
- else
16
- raise ActiveRecord::StatementInvalid, "MySQL server has gone away"
17
- end
18
- end
19
-
20
- def limit_time
21
- @limit_time || 1
22
- end
23
- end
24
- end
25
-
26
- it "enable recovery" do
27
- User3.limit_time = 1
28
- expect {
29
- User3.first
30
- }.not_to raise_error
31
- end
32
-
33
- it "raise exception when retry over" do
34
- User3.limit_time = 100
35
- expect {
36
- User3.first
37
- }.to raise_error(ActiveRecord::StatementInvalid)
38
- end
39
- end