From 01adc45672672459c98880babb39ff5b357e1296 Mon Sep 17 00:00:00 2001 From: Dylan Thacker-Smith Date: Thu, 8 Sep 2016 10:38:58 -0400 Subject: activerecord/mysql2: Avoid setting @connection to nil, just close it By doing `@connection = nil` that means that we need nil checks before it is used anywhere, but we weren't doing those checks. Instead, we get a NoMethodError after using a connection after it fails to reconnect. Neither of the other adapters set @connection to nil, just the mysql2 adapter. By just closing it, we avoid the need to check if we have a connection object and it will produce an appropriate exception when used. --- .../mysql/database_statements.rb | 16 ++++++---------- .../connection_adapters/mysql2_adapter.rb | 6 +----- .../test/cases/adapters/mysql2/connection_test.rb | 21 +++++++++++++++++++++ 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb b/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb index c8238eb266..56800f7590 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb @@ -24,11 +24,9 @@ module ActiveRecord # Executes the SQL statement in the context of this connection. def execute(sql, name = nil) - if @connection - # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been - # made since we established the connection - @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone - end + # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been + # made since we established the connection + @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone super end @@ -71,11 +69,9 @@ module ActiveRecord end def exec_stmt_and_free(sql, name, binds, cache_stmt: false) - if @connection - # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been - # made since we established the connection - @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone - end + # make sure we carry over any changes to ActiveRecord::Base.default_timezone that have been + # made since we established the connection + @connection.query_options[:database_timezone] = ActiveRecord::Base.default_timezone type_casted_binds = type_casted_binds(binds) diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb index 0130b4ef62..a3e2c913c5 100644 --- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb +++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb @@ -90,7 +90,6 @@ module ActiveRecord #++ def active? - return false unless @connection @connection.ping end @@ -105,10 +104,7 @@ module ActiveRecord # Otherwise, this method does nothing. def disconnect! super - unless @connection.nil? - @connection.close - @connection = nil - end + @connection.close end private diff --git a/activerecord/test/cases/adapters/mysql2/connection_test.rb b/activerecord/test/cases/adapters/mysql2/connection_test.rb index 9ede57d395..e014229650 100644 --- a/activerecord/test/cases/adapters/mysql2/connection_test.rb +++ b/activerecord/test/cases/adapters/mysql2/connection_test.rb @@ -63,6 +63,27 @@ class Mysql2ConnectionTest < ActiveRecord::Mysql2TestCase assert @connection.active? end + def test_execute_after_disconnect + @connection.disconnect! + error = assert_raise(ActiveRecord::StatementInvalid) do + @connection.execute("SELECT 1") + end + assert_match /closed MySQL connection/, error.message + end + + def test_quote_after_disconnect + @connection.disconnect! + error = assert_raise(Mysql2::Error) do + @connection.quote("string") + end + assert_match /closed MySQL connection/, error.message + end + + def test_active_after_disconnect + @connection.disconnect! + assert_equal false, @connection.active? + end + def test_mysql_connection_collation_is_configured assert_equal "utf8_unicode_ci", @connection.show_variable("collation_connection") assert_equal "utf8_general_ci", ARUnit2Model.connection.show_variable("collation_connection") -- cgit v1.2.3