seamless_database_pool 1.0.18 → 1.0.20

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: 97df06be58768fd03235c0370d3f6e48a997f720
4
- data.tar.gz: 4175c26ce145bc7e429f7b996a72fda489450506
3
+ metadata.gz: c628c023a3a48064597f57d3aab3eaa36b843516
4
+ data.tar.gz: 26d3ae808291738d05f8ed27d52eca11c70c9983
5
5
  SHA512:
6
- metadata.gz: fab0026bafa0d44e418d1522f0d6ee584b9fcaaa01af1fffe2a3388c93ff52b841656e2e68487d7e7b58ae4bfd757a8532d197157f5e7a677400c37d0bf48092
7
- data.tar.gz: cdb1f53c64c9798e252ad7016d04d3fc5c771195cba4a6745a7b31eee5fa8d8c68def54dfc94db7b23e6bb83b287d4546423bbd03916374be85f7092bc6c8f87
6
+ metadata.gz: 04f6f9d7b8f15bec686fab951c1f87f0a36641ee00371a69cb78e9c31b41e21a1053fae5f1690cddcddd2705aa83e290907be0adf10273b944f7181046ce1bf5
7
+ data.tar.gz: 32bdc669ea87870be6affafd889cb7893e24a50ade3ddf8fbff6b4386c89fa0cb2c0f28aebe7dcbf7b8b949cc404140b7ae4ecb3545584e0e431a02a3714865b
@@ -0,0 +1,93 @@
1
+ ## 1.0.20
2
+
3
+ * Remove calls to `alias_method_chain` for Rails 5.1 compatibility (thanks )
4
+
5
+ * Don't check read only connections on calls to `verify!` and `active?` when not necessary (thanks wjordan)
6
+
7
+ ## 1.0.19
8
+
9
+ * Require ruby 2.0 or greater
10
+
11
+ * Eliminate deprecation warning on Rails 5 (thanks wjordan)
12
+
13
+ ## 1.0.18
14
+
15
+ * ActiveRecord 5.0 compatibility (thanks jkowens)
16
+
17
+ * End support for ActiveRecord 3.1
18
+
19
+ ## 1.0.17
20
+
21
+ * Do not update the HTTP session if there are no changes.
22
+
23
+ ## 1.0.16
24
+
25
+ * Use shorter to_s output for output on connection.inspect.
26
+
27
+ ## 1.0.15
28
+
29
+ * Implement less wordy connection to string method so logs don't fill up with long messages on connection errors.
30
+
31
+ * Update specs to remove deprecation warnings
32
+
33
+ * Fix adapter specs to work with ActiveRecord 4.1 configuration changes
34
+
35
+ ## 1.0.14
36
+
37
+ * Remove custom connection timeout logic; Use the underlying driver's timeouts instead.
38
+
39
+ * Fix to work with query cache.
40
+
41
+ * Make driver less aggressive about overriding methods to proxy to the master connection.
42
+
43
+ * End support for ActiveRecord 2.x
44
+
45
+ * Add support for ActiveRecord 4.0
46
+
47
+ ## 1.0.13
48
+
49
+ * Fix to work with `rake db:*` Rails tasks by removing the adapter from the configuration when db:* tasks are run.
50
+
51
+ * Fix connection pool issues so checkout/checkins don't interact with the underlying connections (thanks afex)
52
+
53
+ * Ruby 2.0/Rails 4.0 compatibility (thanks t27duck)
54
+
55
+ ## 1.0.12
56
+
57
+ * Remove excessively long log messages on reconnect attempts.
58
+
59
+ ## 1.0.11
60
+
61
+ * Remove debug code that prevented recovering from errors.
62
+
63
+ ## 1.0.10
64
+
65
+ * Compatibility with ActiveRecord 3.1.0
66
+
67
+ ## 1.0.9
68
+
69
+ * Compatibility with bind variables.
70
+
71
+ ## 1.0.8
72
+
73
+ * Compatibility with ActiveRecord 3.1.0rc4
74
+
75
+ ## 1.0.7
76
+
77
+ * Make compatible with ActionController 3.0
78
+
79
+ * Improved handling of down slave instances.
80
+
81
+ ## 1.0.6
82
+
83
+ * Make compatible with ActiveRecord 3.0.
84
+
85
+ * Make compatible with database adapters other than MySQL including PostgrSQL.
86
+
87
+ * Better test suite to actually hit three different database adapters.
88
+
89
+ ## 1.0.5
90
+
91
+ * Update docs.
92
+
93
+ * Remove rake dependency on rspec
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 Brian Durand
1
+ Copyright (c) 2008-2017 Brian Durand
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -53,6 +53,7 @@ By default, the master connection will be included in the read pool. If you woul
53
53
  username: read_user
54
54
  password: abc123
55
55
  pool_adapter: mysql2
56
+ prepared_statements: false # required for ActiveRecord 5
56
57
  port: 3306
57
58
  master:
58
59
  host: master-db.example.com
@@ -66,7 +67,7 @@ By default, the master connection will be included in the read pool. If you woul
66
67
 
67
68
  In this configuration, the master connection will be a mysql connection to master-db.example.com:6000 using the username master_user and the password 567pass.
68
69
 
69
- The read pool will use three mysql connections to master-db, read-db-1, and read-db-2. The master connection will use a different port, username, password for the connection. The read connections will use the same values. Further, the connection read-db-1 will get half the traffic as the other two connections, so presumably it's on a more powerful box.
70
+ The read pool will use three mysql connections to master-db, read-db-1, and read-db-2. The master connection will use a different port, username, password for the connection. The read connections will use the same values. Further, the connection read-db-1 will get twice as many read requests as each of the other two connections, so presumably it's on a more powerful box.
70
71
 
71
72
  You must use compatible database adapters for both the master and the read connections. For example, you cannot use an Oracle server as your master and PostgreSQL servers as you read slaves.
72
73
 
@@ -80,4 +81,4 @@ This is done with static methods on SeamlessDatabasePool.
80
81
 
81
82
  To ease integration into a Ruby on Rails application, several controller filters are provided to invoke the above connection methods in a block. These are not implemented as standard controller filters so that the connection methods can be in effect for other filters.
82
83
 
83
- See SeamlessDatabasePool::ControllerFilter for more details.
84
+ See SeamlessDatabasePool::ControllerFilter for more details.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.0.18
1
+ 1.0.20
@@ -50,7 +50,7 @@ module ActiveRecord
50
50
  begin
51
51
  require "active_record/connection_adapters/#{adapter}_adapter"
52
52
  rescue LoadError
53
- raise "Please install the #{adapter} adapter: `gem install activerecord-#{adapter}-adapter` (#{$!})"
53
+ raise LoadError.new("Please install the #{adapter} adapter: `gem install activerecord-#{adapter}-adapter` (#{$!})")
54
54
  end
55
55
  end
56
56
 
@@ -62,19 +62,16 @@ module ActiveRecord
62
62
  end
63
63
 
64
64
  module SeamlessDatabasePoolBehavior
65
- def self.included(base)
66
- base.alias_method_chain(:reload, :seamless_database_pool)
67
- end
68
65
 
69
66
  # Force reload to use the master connection since it's probably being called for a reason.
70
- def reload_with_seamless_database_pool(*args)
67
+ def reload(*args)
71
68
  SeamlessDatabasePool.use_master_connection do
72
- reload_without_seamless_database_pool(*args)
69
+ super *args
73
70
  end
74
71
  end
75
72
  end
76
73
 
77
- include(SeamlessDatabasePoolBehavior) unless include?(SeamlessDatabasePoolBehavior)
74
+ prepend SeamlessDatabasePoolBehavior
78
75
  end
79
76
 
80
77
  module ConnectionAdapters
@@ -99,6 +96,7 @@ module ActiveRecord
99
96
  override_classes.each do |connection_class|
100
97
  master_methods.concat(connection_class.public_instance_methods(false))
101
98
  master_methods.concat(connection_class.protected_instance_methods(false))
99
+ master_methods.concat(connection_class.private_instance_methods(false))
102
100
  end
103
101
  master_methods = master_methods.collect{|m| m.to_sym}.uniq
104
102
  master_methods -= public_instance_methods(false) + protected_instance_methods(false) + private_instance_methods(false)
@@ -199,9 +197,13 @@ module ActiveRecord
199
197
  end
200
198
 
201
199
  def active?
202
- active = true
203
- do_to_connections {|conn| active &= conn.active?}
204
- return active
200
+ if SeamlessDatabasePool.read_only_connection_type == :master
201
+ @master_connection.active?
202
+ else
203
+ active = true
204
+ do_to_connections {|conn| active &= conn.active?}
205
+ active
206
+ end
205
207
  end
206
208
 
207
209
  def reconnect!
@@ -217,7 +219,11 @@ module ActiveRecord
217
219
  end
218
220
 
219
221
  def verify!(*ignored)
220
- do_to_connections {|conn| conn.verify!(*ignored)}
222
+ if SeamlessDatabasePool.read_only_connection_type == :master
223
+ @master_connection.verify!(*ignored)
224
+ else
225
+ do_to_connections {|conn| conn.verify!(*ignored)}
226
+ end
221
227
  end
222
228
 
223
229
  def reset_runtime
@@ -14,7 +14,7 @@ module Arel
14
14
  # try to load an externally defined compiler, in case this adapter has defined the compiler on its own.
15
15
  require "#{master_adapter.downcase}/arel_compiler"
16
16
  rescue LoadError
17
- raise "#{master_adapter} is not supported by Arel."
17
+ raise LoadError.new("#{master_adapter} is not supported by Arel.")
18
18
  end
19
19
  end
20
20
  compiler_class = Arel::SqlCompiler.const_get("#{master_adapter}Compiler")
@@ -3,48 +3,41 @@ module SeamlessDatabasePool
3
3
  # and it will keep track of how often each connection calls update, insert, execute,
4
4
  # or select.
5
5
  module ConnectionStatistics
6
- def self.included(base)
7
- base.alias_method_chain(:update, :connection_statistics)
8
- base.alias_method_chain(:insert, :connection_statistics)
9
- base.alias_method_chain(:execute, :connection_statistics)
10
- base.alias_method_chain(:select, :connection_statistics)
11
- end
12
-
13
6
  # Get the connection statistics
14
7
  def connection_statistics
15
8
  @connection_statistics ||= {}
16
9
  end
17
-
10
+
18
11
  def reset_connection_statistics
19
12
  @connection_statistics = {}
20
13
  end
21
-
22
- def update_with_connection_statistics(sql, name = nil)
14
+
15
+ def update(sql, name = nil)
23
16
  increment_connection_statistic(:update) do
24
- update_without_connection_statistics(sql, name)
17
+ super(sql, name)
25
18
  end
26
19
  end
27
-
28
- def insert_with_connection_statistics(sql, name = nil)
20
+
21
+ def insert(sql, name = nil)
29
22
  increment_connection_statistic(:insert) do
30
- insert_without_connection_statistics(sql, name)
23
+ super(sql, name)
31
24
  end
32
25
  end
33
-
34
- def execute_with_connection_statistics(sql, name = nil)
26
+
27
+ def execute(sql, name = nil)
35
28
  increment_connection_statistic(:execute) do
36
- execute_without_connection_statistics(sql, name)
29
+ super(sql, name)
37
30
  end
38
31
  end
39
-
32
+
40
33
  protected
41
-
42
- def select_with_connection_statistics(sql, name = nil, *args)
34
+
35
+ def select(sql, name = nil, *args)
43
36
  increment_connection_statistic(:select) do
44
- select_without_connection_statistics(sql, name, *args)
37
+ super(sql, name, *args)
45
38
  end
46
39
  end
47
-
40
+
48
41
  def increment_connection_statistic(method)
49
42
  if @counting_pool_statistics
50
43
  yield
@@ -6,35 +6,28 @@ module SeamlessDatabasePool
6
6
  # when you need different connection types.
7
7
  #
8
8
  # Example:
9
- #
9
+ #
10
10
  # ApplicationController < ActionController::Base
11
11
  # include SeamlessDatabasePool::ControllerFilter
12
12
  # use_database_pool :all => :persistent, [:save, :delete] => :master
13
13
  # ...
14
-
15
- module ControllerFilter
14
+ module ControllerFilter
16
15
  def self.included(base)
17
16
  unless base.respond_to?(:use_database_pool)
18
17
  base.extend(ClassMethods)
19
18
  base.class_eval do
20
- if base.method_defined?(:perform_action) || base.private_method_defined?(:perform_action)
21
- alias_method_chain :perform_action, :seamless_database_pool
22
- else
23
- alias_method_chain :process, :seamless_database_pool
24
- end
25
- alias_method_chain :redirect_to, :seamless_database_pool
19
+ send(:prepend, ControllerFilterHooks)
26
20
  end
27
21
  end
28
22
  end
29
-
23
+
30
24
  module ClassMethods
31
-
32
25
  def seamless_database_pool_options
33
26
  return @seamless_database_pool_options if @seamless_database_pool_options
34
27
  @seamless_database_pool_options = superclass.seamless_database_pool_options.dup if superclass.respond_to?(:seamless_database_pool_options)
35
28
  @seamless_database_pool_options ||= {}
36
29
  end
37
-
30
+
38
31
  # Call this method to set up the connection types that will be used for your actions.
39
32
  # The configuration is given as a hash where the key is the action name and the value is
40
33
  # the connection type (:master, :persistent, or :random). You can specify :all as the action
@@ -58,7 +51,7 @@ module SeamlessDatabasePool
58
51
  @seamless_database_pool_options = remapped_options
59
52
  end
60
53
  end
61
-
54
+
62
55
  # Force the master connection to be used on the next request. This is very useful for the Post-Redirect pattern
63
56
  # where you post a request to your save action and then redirect the user back to the edit action. By calling
64
57
  # this method, you won't have to worry if the replication engine is slower than the redirect. Normally you
@@ -68,34 +61,13 @@ module SeamlessDatabasePool
68
61
  def use_master_db_connection_on_next_request
69
62
  session[:next_request_db_connection] = :master if session
70
63
  end
71
-
64
+
72
65
  def seamless_database_pool_options
73
66
  self.class.seamless_database_pool_options
74
67
  end
75
-
76
- # Rails 3.x hook for setting the read connection for the request.
77
- def process_with_seamless_database_pool(action, *args)
78
- set_read_only_connection_for_block(action) do
79
- process_without_seamless_database_pool(action, *args)
80
- end
81
- end
82
-
83
- def redirect_to_with_seamless_database_pool(options = {}, response_status = {})
84
- if SeamlessDatabasePool.read_only_connection_type(nil) == :master
85
- use_master_db_connection_on_next_request
86
- end
87
- redirect_to_without_seamless_database_pool(options, response_status)
88
- end
89
-
68
+
90
69
  private
91
-
92
- # Rails 2.x hook for setting the read connection for the request.
93
- def perform_action_with_seamless_database_pool(*args)
94
- set_read_only_connection_for_block(action_name) do
95
- perform_action_without_seamless_database_pool(*args)
96
- end
97
- end
98
-
70
+
99
71
  # Set the read only connection for a block. Used to set the connection for a controller action.
100
72
  def set_read_only_connection_for_block(action)
101
73
  read_pool_method = nil
@@ -103,7 +75,7 @@ module SeamlessDatabasePool
103
75
  read_pool_method = session[:next_request_db_connection]
104
76
  session.delete(:next_request_db_connection) if session[:next_request_db_connection]
105
77
  end
106
-
78
+
107
79
  read_pool_method ||= seamless_database_pool_options[action.to_sym] || seamless_database_pool_options[:all]
108
80
  if read_pool_method
109
81
  SeamlessDatabasePool.set_read_only_connection_type(read_pool_method) do
@@ -114,4 +86,28 @@ module SeamlessDatabasePool
114
86
  end
115
87
  end
116
88
  end
89
+
90
+ module ControllerFilterHooks
91
+ # Rails 3.x hook for setting the read connection for the request.
92
+ def process(action, *args)
93
+ set_read_only_connection_for_block(action) do
94
+ super(action, *args)
95
+ end
96
+ end
97
+
98
+ # Rails 2.x hook for setting the read connection for the request.
99
+ def perform_action(*args)
100
+ set_read_only_connection_for_block(action_name) do
101
+ super
102
+ end
103
+ end
104
+
105
+ def redirect_to(options = {}, response_status = {})
106
+ if SeamlessDatabasePool.read_only_connection_type(nil) == :master
107
+ use_master_db_connection_on_next_request
108
+ end
109
+
110
+ super(options, response_status)
111
+ end
112
+ end
117
113
  end
@@ -4,8 +4,12 @@ module SeamlessDatabasePool
4
4
  namespace :db do
5
5
  task :load_config do
6
6
  # Override seamless_database_pool configuration so db:* rake tasks work as expected.
7
- original_config = Rails.application.config.database_configuration
8
- ActiveRecord::Base.configurations = SeamlessDatabasePool.master_database_configuration(original_config)
7
+ module DatabaseConfiguration
8
+ def configurations
9
+ SeamlessDatabasePool.master_database_configuration(super.deep_dup)
10
+ end
11
+ end
12
+ ActiveRecord::Base.singleton_class.prepend(DatabaseConfiguration)
9
13
  end
10
14
  end
11
15
  end
@@ -12,8 +12,9 @@ Gem::Specification.new do |spec|
12
12
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
13
13
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
14
14
  spec.require_paths = ["lib"]
15
+ spec.required_ruby_version = '~> 2.0'
15
16
 
16
- spec.add_runtime_dependency(%q<activerecord>, [">= 3.0.20"])
17
+ spec.add_runtime_dependency(%q<activerecord>, [">= 3.2.0"])
17
18
  spec.add_development_dependency(%q<rspec>, [">= 2.0"])
18
19
  spec.add_development_dependency(%q<sqlite3>, [">= 0"])
19
20
  spec.add_development_dependency(%q<mysql>, [">= 0"])
@@ -13,7 +13,7 @@ describe "Test connection adapters" do
13
13
  let(:master_connection){ connection.master_connection }
14
14
 
15
15
  before(:all) do
16
- if ActiveRecord::VERSION::MAJOR < 3 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 0)
16
+ if ActiveRecord::VERSION::MAJOR < 4 || (ActiveRecord::VERSION::MAJOR == 4 && ActiveRecord::VERSION::MINOR == 0)
17
17
  ActiveRecord::Base.configurations = {'adapter' => "sqlite3", 'database' => ":memory:"}
18
18
  else
19
19
  ActiveRecord::Base.configurations = {"test" => {'adapter' => "sqlite3", 'database' => ":memory:"}}
@@ -230,6 +230,19 @@ describe "Test connection adapters" do
230
230
 
231
231
  with_driver.string.should == without_driver.string
232
232
  end
233
+
234
+ it "should allow for database specific types" do
235
+ if adapter == "postgresql"
236
+ SeamlessDatabasePool.use_master_connection do
237
+ connection.enable_extension "hstore"
238
+ connection.create_table(:pg) do |t|
239
+ t.hstore :my_hash
240
+ end
241
+ end
242
+ connection.drop_table(:pg)
243
+ end
244
+ end
245
+
233
246
  end
234
247
  end
235
248
  end
@@ -1,32 +1,31 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SeamlessDatabasePool::ConnectionStatistics do
4
-
5
4
  module SeamlessDatabasePool
6
5
  class ConnectionStatisticsTester
7
6
  def insert (sql, name = nil)
8
7
  "INSERT #{sql}/#{name}"
9
8
  end
10
-
9
+
11
10
  def update (sql, name = nil)
12
11
  execute(sql)
13
12
  "UPDATE #{sql}/#{name}"
14
13
  end
15
-
14
+
16
15
  def execute (sql, name = nil)
17
16
  "EXECUTE #{sql}/#{name}"
18
17
  end
19
-
18
+
20
19
  protected
21
-
20
+
22
21
  def select (sql, name = nil, binds = [])
23
22
  "SELECT #{sql}/#{name}"
24
23
  end
25
-
26
- include ::SeamlessDatabasePool::ConnectionStatistics
24
+
25
+ prepend ::SeamlessDatabasePool::ConnectionStatistics
27
26
  end
28
27
  end
29
-
28
+
30
29
  it "should increment statistics on update" do
31
30
  connection = SeamlessDatabasePool::ConnectionStatisticsTester.new
32
31
  connection.update('SQL', 'name').should == "UPDATE SQL/name"
@@ -34,7 +33,7 @@ describe SeamlessDatabasePool::ConnectionStatistics do
34
33
  connection.update('SQL 2').should == "UPDATE SQL 2/"
35
34
  connection.connection_statistics.should == {:update => 2}
36
35
  end
37
-
36
+
38
37
  it "should increment statistics on insert" do
39
38
  connection = SeamlessDatabasePool::ConnectionStatisticsTester.new
40
39
  connection.insert('SQL', 'name').should == "INSERT SQL/name"
@@ -42,7 +41,7 @@ describe SeamlessDatabasePool::ConnectionStatistics do
42
41
  connection.insert('SQL 2').should == "INSERT SQL 2/"
43
42
  connection.connection_statistics.should == {:insert => 2}
44
43
  end
45
-
44
+
46
45
  it "should increment statistics on execute" do
47
46
  connection = SeamlessDatabasePool::ConnectionStatisticsTester.new
48
47
  connection.execute('SQL', 'name').should == "EXECUTE SQL/name"
@@ -50,7 +49,7 @@ describe SeamlessDatabasePool::ConnectionStatistics do
50
49
  connection.execute('SQL 2').should == "EXECUTE SQL 2/"
51
50
  connection.connection_statistics.should == {:execute => 2}
52
51
  end
53
-
52
+
54
53
  it "should increment statistics on select" do
55
54
  connection = SeamlessDatabasePool::ConnectionStatisticsTester.new
56
55
  connection.send(:select, 'SQL', 'name').should == "SELECT SQL/name"
@@ -58,14 +57,14 @@ describe SeamlessDatabasePool::ConnectionStatistics do
58
57
  connection.send(:select, 'SQL 2').should == "SELECT SQL 2/"
59
58
  connection.connection_statistics.should == {:select => 2}
60
59
  end
61
-
60
+
62
61
  it "should increment counts only once within a block" do
63
62
  connection = SeamlessDatabasePool::ConnectionStatisticsTester.new
64
63
  expect(connection).to receive(:execute).with('SQL')
65
64
  connection.update('SQL')
66
65
  connection.connection_statistics.should == {:update => 1}
67
66
  end
68
-
67
+
69
68
  it "should be able to clear the statistics" do
70
69
  connection = SeamlessDatabasePool::ConnectionStatisticsTester.new
71
70
  connection.update('SQL')
@@ -73,5 +72,5 @@ describe SeamlessDatabasePool::ConnectionStatistics do
73
72
  connection.reset_connection_statistics
74
73
  connection.connection_statistics.should == {}
75
74
  end
76
-
75
+
77
76
  end
@@ -1,45 +1,45 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe "SeamlessDatabasePool::ControllerFilter" do
4
-
4
+
5
5
  module SeamlessDatabasePool
6
6
  class TestApplicationController
7
7
  attr_reader :session
8
-
8
+
9
9
  def initialize(session)
10
10
  @session = session
11
11
  end
12
-
12
+
13
13
  def process(action, *args)
14
14
  send action
15
15
  end
16
-
16
+
17
17
  def redirect_to (options = {}, response_status = {})
18
18
  options
19
19
  end
20
-
20
+
21
21
  def base_action
22
22
  ::SeamlessDatabasePool.read_only_connection_type
23
23
  end
24
24
  end
25
-
25
+
26
26
  class TestBaseController < TestApplicationController
27
27
  include ::SeamlessDatabasePool::ControllerFilter
28
28
 
29
29
  use_database_pool :read => :persistent
30
-
30
+
31
31
  def read
32
32
  ::SeamlessDatabasePool.read_only_connection_type
33
33
  end
34
-
34
+
35
35
  def other
36
36
  ::SeamlessDatabasePool.read_only_connection_type
37
37
  end
38
38
  end
39
-
39
+
40
40
  class TestOtherController < TestBaseController
41
41
  use_database_pool :all => :random, [:edit, :save, :redirect_master_action] => :master
42
-
42
+
43
43
  def edit
44
44
  ::SeamlessDatabasePool.read_only_connection_type
45
45
  end
@@ -47,102 +47,102 @@ describe "SeamlessDatabasePool::ControllerFilter" do
47
47
  def save
48
48
  ::SeamlessDatabasePool.read_only_connection_type
49
49
  end
50
-
50
+
51
51
  def redirect_master_action
52
52
  redirect_to(:action => :read)
53
53
  end
54
-
54
+
55
55
  def redirect_read_action
56
56
  redirect_to(:action => :read)
57
57
  end
58
58
  end
59
-
59
+
60
60
  class TestRails2ApplicationController < TestApplicationController
61
61
  attr_reader :action_name
62
-
62
+
63
63
  def process(action, *args)
64
64
  @action_name = action
65
65
  perform_action
66
66
  end
67
-
67
+
68
68
  private
69
-
69
+
70
70
  def perform_action
71
71
  send action_name
72
72
  end
73
73
  end
74
-
74
+
75
75
  class TestRails2BaseController < TestRails2ApplicationController
76
76
  include ::SeamlessDatabasePool::ControllerFilter
77
77
 
78
78
  use_database_pool :read => :persistent
79
-
79
+
80
80
  def read
81
81
  ::SeamlessDatabasePool.read_only_connection_type
82
82
  end
83
83
  end
84
84
  end
85
-
85
+
86
86
  let(:session){Hash.new}
87
87
  let(:controller){SeamlessDatabasePool::TestOtherController.new(session)}
88
-
88
+
89
89
  it "should work with nothing set" do
90
90
  controller = SeamlessDatabasePool::TestApplicationController.new(session)
91
91
  controller.process('base_action').should == :master
92
92
  end
93
-
93
+
94
94
  it "should allow setting a connection type for a single action" do
95
95
  controller = SeamlessDatabasePool::TestBaseController.new(session)
96
96
  controller.process('read').should == :persistent
97
97
  end
98
-
98
+
99
99
  it "should allow setting a connection type for actions" do
100
100
  controller.process('edit').should == :master
101
101
  controller.process('save').should == :master
102
102
  end
103
-
103
+
104
104
  it "should allow setting a connection type for all actions" do
105
105
  controller.process('other').should == :random
106
106
  end
107
-
107
+
108
108
  it "should inherit the superclass' options" do
109
109
  controller.process('read').should == :persistent
110
110
  end
111
-
111
+
112
112
  it "should be able to force using the master connection on the next request" do
113
113
  # First request
114
114
  controller.process('read').should == :persistent
115
115
  controller.use_master_db_connection_on_next_request
116
-
116
+
117
117
  # Second request
118
118
  controller.process('read').should == :master
119
-
119
+
120
120
  # Third request
121
121
  controller.process('read').should == :persistent
122
122
  end
123
-
123
+
124
124
  it "should not break trying to force the master connection if sessions are not enabled" do
125
125
  controller.process('read').should == :persistent
126
126
  controller.use_master_db_connection_on_next_request
127
-
127
+
128
128
  # Second request
129
129
  session.clear
130
130
  controller.process('read').should == :persistent
131
131
  end
132
-
132
+
133
133
  it "should force the master connection on the next request for a redirect in master connection block" do
134
134
  controller = SeamlessDatabasePool::TestOtherController.new(session)
135
135
  controller.process('redirect_master_action').should == {:action => :read}
136
-
136
+
137
137
  controller.process('read').should == :master
138
138
  end
139
139
 
140
140
  it "should not force the master connection on the next request for a redirect not in master connection block" do
141
141
  controller.process('redirect_read_action').should == {:action => :read}
142
-
142
+
143
143
  controller.process('read').should == :persistent
144
144
  end
145
-
145
+
146
146
  it "should work with a Rails 2 controller" do
147
147
  controller = SeamlessDatabasePool::TestRails2BaseController.new(session)
148
148
  controller.process('read').should == :persistent
@@ -5,6 +5,7 @@
5
5
  sqlite3:
6
6
  adapter: seamless_database_pool
7
7
  database: test.sqlite3
8
+ prepared_statements: false
8
9
  master:
9
10
  adapter: sqlite3
10
11
  pool_weight: 0
@@ -15,6 +16,7 @@ sqlite3:
15
16
  postgresql:
16
17
  adapter: seamless_database_pool
17
18
  database: seamless_database_pool_test
19
+ prepared_statements: false
18
20
  username: postgres
19
21
  password: postgres
20
22
  master:
@@ -189,27 +189,54 @@ describe "SeamlessDatabasePoolAdapter" do
189
189
  end
190
190
 
191
191
  context "fork to all connections" do
192
- it "should fork active? to all connections and return true if all are up" do
193
- expect(master_connection).to receive(:active?).and_return(true)
194
- expect(read_connection_1).to receive(:active?).and_return(true)
195
- expect(read_connection_2).to receive(:active?).and_return(true)
196
- pool_connection.active?.should == true
197
- end
198
-
199
- it "should fork active? to all connections and return false if one is down" do
200
- expect(master_connection).to receive(:active?).and_return(true)
201
- expect(read_connection_1).to receive(:active?).and_return(true)
202
- expect(read_connection_2).to receive(:active?).and_return(false)
203
- pool_connection.active?.should == false
192
+ context "when read-only connection type is master" do
193
+ it "should fork active? to master connection only" do
194
+ expect(master_connection).to receive(:active?).and_return(true)
195
+ expect(read_connection_1).not_to receive(:active?)
196
+ expect(read_connection_2).not_to receive(:active?)
197
+ pool_connection.active?.should == true
198
+ end
199
+
200
+ it "should fork verify! to master connection only" do
201
+ expect(master_connection).to receive(:verify!).with(5)
202
+ expect(read_connection_1).not_to receive(:verify!)
203
+ expect(read_connection_2).not_to receive(:verify!)
204
+ pool_connection.verify!(5)
205
+ end
204
206
  end
205
-
206
- it "should fork verify! to all connections" do
207
- expect(master_connection).to receive(:verify!).with(5)
208
- expect(read_connection_1).to receive(:verify!).with(5)
209
- expect(read_connection_2).to receive(:verify!).with(5)
210
- pool_connection.verify!(5)
207
+
208
+ context "When read-only connection type is persistent or random" do
209
+ around do |example|
210
+ SeamlessDatabasePool.set_read_only_connection_type(:persistent) do
211
+ example.run
212
+ end
213
+ SeamlessDatabasePool.set_read_only_connection_type(:random) do
214
+ example.run
215
+ end
216
+ end
217
+
218
+ it "should fork active? to all connections and return true if all are up" do
219
+ expect(master_connection).to receive(:active?).and_return(true)
220
+ expect(read_connection_1).to receive(:active?).and_return(true)
221
+ expect(read_connection_2).to receive(:active?).and_return(true)
222
+ pool_connection.active?.should == true
223
+ end
224
+
225
+ it "should fork active? to all connections and return false if one is down" do
226
+ expect(master_connection).to receive(:active?).and_return(true)
227
+ expect(read_connection_1).to receive(:active?).and_return(true)
228
+ expect(read_connection_2).to receive(:active?).and_return(false)
229
+ pool_connection.active?.should == false
230
+ end
231
+
232
+ it "should fork verify! to all connections" do
233
+ expect(master_connection).to receive(:verify!).with(5)
234
+ expect(read_connection_1).to receive(:verify!).with(5)
235
+ expect(read_connection_2).to receive(:verify!).with(5)
236
+ pool_connection.verify!(5)
237
+ end
211
238
  end
212
-
239
+
213
240
  it "should fork disconnect! to all connections" do
214
241
  expect(master_connection).to receive(:disconnect!)
215
242
  expect(read_connection_1).to receive(:disconnect!)
@@ -22,4 +22,5 @@ RSpec.configure do |config|
22
22
  # --seed 1234
23
23
  config.order = 'random'
24
24
  config.expect_with(:rspec) { |c| c.syntax = [:should, :expect] }
25
+ config.mock_with(:rspec) { |c| c.syntax = [:should, :expect] }
25
26
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: seamless_database_pool
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.18
4
+ version: 1.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brian Durand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-05-30 00:00:00.000000000 Z
11
+ date: 2017-05-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 3.0.20
19
+ version: 3.2.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 3.0.20
26
+ version: 3.2.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rspec
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -90,7 +90,7 @@ extra_rdoc_files: []
90
90
  files:
91
91
  - ".gitignore"
92
92
  - ".travis.yml"
93
- - HISTORY.txt
93
+ - CHANGELOG.md
94
94
  - MIT-LICENSE
95
95
  - README.rdoc
96
96
  - Rakefile
@@ -121,9 +121,9 @@ require_paths:
121
121
  - lib
122
122
  required_ruby_version: !ruby/object:Gem::Requirement
123
123
  requirements:
124
- - - ">="
124
+ - - "~>"
125
125
  - !ruby/object:Gem::Version
126
- version: '0'
126
+ version: '2.0'
127
127
  required_rubygems_version: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
@@ -131,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
131
  version: '0'
132
132
  requirements: []
133
133
  rubyforge_project:
134
- rubygems_version: 2.4.5
134
+ rubygems_version: 2.6.11
135
135
  signing_key:
136
136
  specification_version: 4
137
137
  summary: Add support for master/slave database clusters in ActiveRecord to improve
@@ -1,79 +0,0 @@
1
- 1.0.18
2
-
3
- ActiveRecord 5.0 compatibility (thanks jkowens)
4
-
5
- 1.0.17
6
-
7
- Do not update the HTTP session if there are no changes.
8
-
9
- 1.0.16
10
-
11
- Use shorter to_s output for output on connection.inspect.
12
-
13
- 1.0.15
14
-
15
- Implement less wordy connection to string method so logs don't fill up with long messages on connection errors.
16
-
17
- Update specs to remove deprecation warnings
18
-
19
- Fix adapter specs to work with ActiveRecord 4.1 configuration changes
20
-
21
- 1.0.14
22
-
23
- Remove custom connection timeout logic; Use the underlying driver's timeouts instead.
24
-
25
- Fix to work with query cache.
26
-
27
- Make driver less aggressive about overriding methods to proxy to the master connection.
28
-
29
- End support for ActiveRecord 2.x
30
-
31
- Add support for ActiveRecord 4.0
32
-
33
- 1.0.13
34
-
35
- Fix to work with `rake db:*` Rails tasks by removing the adapter from the configuration when db:* tasks are run.
36
-
37
- Fix connection pool issues so checkout/checkins don't interact with the underlying connections (thanks afex)
38
-
39
- Ruby 2.0/Rails 4.0 compatibility (thanks t27duck)
40
-
41
- 1.0.12
42
-
43
- Remove excessively long log messages on reconnect attempts.
44
-
45
- 1.0.11
46
-
47
- Remove debug code that prevented recovering from errors.
48
-
49
- 1.0.10
50
-
51
- Compatibility with ActiveRecord 3.1.0
52
-
53
- 1.0.9
54
-
55
- Compatibility with bind variables.
56
-
57
- 1.0.8
58
-
59
- Compatibility with ActiveRecord 3.1.0rc4
60
-
61
- 1.0.7
62
-
63
- Make compatible with ActionController 3.0
64
-
65
- Improved handling of down slave instances.
66
-
67
- 1.0.6
68
-
69
- Make compatible with ActiveRecord 3.0.
70
-
71
- Make compatible with database adapters other than MySQL including PostgrSQL.
72
-
73
- Better test suite to actually hit three different database adapters.
74
-
75
- 1.0.5
76
-
77
- Update docs.
78
-
79
- Remove rake dependency on rspec