fresh_connection 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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