From bf79aa4fc14aeb2646331e767038acf0b77e9e7f Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Sun, 27 Dec 2015 23:12:41 +0900
Subject: Improve `select_one` in `Mysql2Adapter`

Avoid instanciate `ActiveRecord::Result` and calling
`ActiveRecord::Result#hash_rows` for the performance.
---
 .../lib/active_record/connection_adapters/mysql2_adapter.rb    | 10 ++++++++++
 activerecord/test/cases/adapters/mysql2/sp_test.rb             |  6 ++++++
 2 files changed, 16 insertions(+)

(limited to 'activerecord')

diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index f4686b680c..7fbe2307c7 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -127,6 +127,16 @@ module ActiveRecord
       #   execute(sql, name).map { |row| row.first }
       # end
 
+      # Returns a record hash with the column names as keys and column values
+      # as values.
+      def select_one(arel, name = nil, binds = [])
+        arel, binds = binds_from_relation(arel, binds)
+        execute(to_sql(arel, binds), name).each(as: :hash) do |row|
+          @connection.next_result while @connection.more_results?
+          return row
+        end
+      end
+
       # Returns an array of arrays containing the field values.
       # Order is the same as that returned by +columns+.
       def select_rows(sql, name = nil, binds = [])
diff --git a/activerecord/test/cases/adapters/mysql2/sp_test.rb b/activerecord/test/cases/adapters/mysql2/sp_test.rb
index cdaa2cca44..4197ba45f1 100644
--- a/activerecord/test/cases/adapters/mysql2/sp_test.rb
+++ b/activerecord/test/cases/adapters/mysql2/sp_test.rb
@@ -22,6 +22,12 @@ class Mysql2StoredProcedureTest < ActiveRecord::Mysql2TestCase
     assert @connection.active?, "Bad connection use by 'Mysql2Adapter.select_rows'"
   end
 
+  def test_multi_results_from_select_one
+    row = @connection.select_one('CALL topics(1);')
+    assert_equal 'David', row['author_name']
+    assert @connection.active?, "Bad connection use by 'Mysql2Adapter.select_one'"
+  end
+
   def test_multi_results_from_find_by_sql
     topics = Topic.find_by_sql 'CALL topics(3);'
     assert_equal 3, topics.size
-- 
cgit v1.2.3


From 7f43485508a277c43c046c5a701f6bdb6aed1ede Mon Sep 17 00:00:00 2001
From: Ryuta Kamizono <kamipo@gmail.com>
Date: Sun, 27 Dec 2015 23:30:21 +0900
Subject: Remove outdated comment

These `select_*` methods improved already.
---
 .../connection_adapters/mysql2_adapter.rb          | 28 ----------------------
 1 file changed, 28 deletions(-)

(limited to 'activerecord')

diff --git a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
index 7fbe2307c7..96a3a44b30 100644
--- a/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/mysql2_adapter.rb
@@ -99,34 +99,6 @@ module ActiveRecord
       # DATABASE STATEMENTS ======================================
       #++
 
-      # FIXME: re-enable the following once a "better" query_cache solution is in core
-      #
-      # The overrides below perform much better than the originals in AbstractAdapter
-      # because we're able to take advantage of mysql2's lazy-loading capabilities
-      #
-      # # Returns a record hash with the column names as keys and column values
-      # # as values.
-      # def select_one(sql, name = nil)
-      #   result = execute(sql, name)
-      #   result.each(as: :hash) do |r|
-      #     return r
-      #   end
-      # end
-      #
-      # # Returns a single value from a record
-      # def select_value(sql, name = nil)
-      #   result = execute(sql, name)
-      #   if first = result.first
-      #     first.first
-      #   end
-      # end
-      #
-      # # Returns an array of the values of the first column in a select:
-      # #   select_values("SELECT id FROM companies LIMIT 3") => [1,2,3]
-      # def select_values(sql, name = nil)
-      #   execute(sql, name).map { |row| row.first }
-      # end
-
       # Returns a record hash with the column names as keys and column values
       # as values.
       def select_one(arel, name = nil, binds = [])
-- 
cgit v1.2.3