Skip to content

Commit 68de6ca

Browse files
committed
Optimize #select_one.
1 parent 3519610 commit 68de6ca

File tree

5 files changed

+62
-24
lines changed

5 files changed

+62
-24
lines changed

Diff for: lib/active_record/connection_adapters/sqlserver/database_statements.rb

+34-22
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,14 @@ module ActiveRecord
22
module ConnectionAdapters
33
module Sqlserver
44
module DatabaseStatements
5-
5+
6+
def select_one(sql, name = nil)
7+
result = raw_select sql, name, :fetch => :one
8+
(result && result.first.present?) ? result.first : nil
9+
end
10+
611
def select_rows(sql, name = nil)
7-
raw_select sql, name, true
12+
raw_select sql, name, :fetch => :rows
813
end
914

1015
def execute(sql, name = nil, skip_logging = false)
@@ -70,7 +75,7 @@ def execute_procedure(proc_name, *variables)
7075
log(sql,'Execute Procedure') do
7176
raw_connection_run(sql) do |handle|
7277
get_rows = lambda {
73-
rows = handle_to_names_and_values(handle,false)
78+
rows = handle_to_names_and_values handle, :fetch => :all
7479
rows.each_with_index { |r,i| rows[i] = r.with_indifferent_access }
7580
results << rows
7681
}
@@ -162,7 +167,7 @@ def charset
162167
protected
163168

164169
def select(sql, name = nil)
165-
raw_select(sql,name)
170+
raw_select sql, name, :fetch => :all
166171
end
167172

168173
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
@@ -200,11 +205,11 @@ def raw_connection_do(sql)
200205

201206
# === SQLServer Specific (Selecting) ============================ #
202207

203-
def raw_select(sql, name=nil, rows_only=false)
208+
def raw_select(sql, name=nil, options={})
204209
log(sql,name) do
205210
begin
206211
handle = raw_connection_run(sql)
207-
handle_to_names_and_values(handle, rows_only)
212+
handle_to_names_and_values(handle, options)
208213
ensure
209214
finish_statement_handle(handle)
210215
end
@@ -231,45 +236,52 @@ def handle_more_results?(handle)
231236
end
232237
end
233238

234-
def handle_to_names_and_values(handle, rows_only)
239+
def handle_to_names_and_values(handle, options={})
235240
case connection_mode
236241
when :odbc
237-
handle_to_names_and_values_odbc(handle, rows_only)
242+
handle_to_names_and_values_odbc(handle, options)
238243
when :adonet
239-
handle_to_names_and_values_adonet(handle, rows_only)
244+
handle_to_names_and_values_adonet(handle, options)
240245
end
241246
end
242247

243-
def handle_to_names_and_values_odbc(handle, rows_only)
244-
rows = handle.fetch_all || []
245-
if rows_only
248+
def handle_to_names_and_values_odbc(handle, options={})
249+
case options[:fetch]
250+
when :all, :one
251+
rows = if options[:fetch] == :all
252+
handle.fetch_all || []
253+
else
254+
row = handle.fetch
255+
row ? [row] : [[]]
256+
end
257+
names = handle.columns(true).map{ |c| c.name }
258+
names_and_values = []
246259
rows.each do |row|
260+
h = {}
247261
i = 0
248262
while i < row.size
249263
v = row[i]
250-
row[i] = v.to_sqlserver_string if v.respond_to?(:to_sqlserver_string)
264+
h[names[i]] = v.respond_to?(:to_sqlserver_string) ? v.to_sqlserver_string : v
251265
i += 1
252266
end
267+
names_and_values << h
253268
end
254-
rows
255-
else
256-
names = handle.columns(true).map{ |c| c.name }
257-
names_and_values = []
269+
names_and_values
270+
when :rows
271+
rows = handle.fetch_all || []
258272
rows.each do |row|
259-
h = {}
260273
i = 0
261274
while i < row.size
262275
v = row[i]
263-
h[names[i]] = v.respond_to?(:to_sqlserver_string) ? v.to_sqlserver_string : v
276+
row[i] = v.to_sqlserver_string if v.respond_to?(:to_sqlserver_string)
264277
i += 1
265278
end
266-
names_and_values << h
267279
end
268-
names_and_values
280+
rows
269281
end
270282
end
271283

272-
def handle_to_names_and_values_adonet(handle, rows_only)
284+
def handle_to_names_and_values_adonet(handle, options={})
273285
if handle.has_rows
274286
fields = []
275287
rows = []
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
module ActiveRecord
2+
module ConnectionAdapters
3+
module Sqlserver
4+
module QueryCache
5+
6+
def select_one(*args)
7+
if @query_cache_enabled
8+
cache_sql(args.first) { super }
9+
else
10+
super
11+
end
12+
end
13+
14+
end
15+
end
16+
end
17+
end

Diff for: lib/active_record/connection_adapters/sqlserver_adapter.rb

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
require 'active_record/connection_adapters/sqlserver/database_limits'
55
require 'active_record/connection_adapters/sqlserver/database_statements'
66
require 'active_record/connection_adapters/sqlserver/errors'
7+
require 'active_record/connection_adapters/sqlserver/query_cache'
78
require 'active_record/connection_adapters/sqlserver/schema_statements'
89
require 'active_record/connection_adapters/sqlserver/quoting'
910
require 'active_support/core_ext/kernel/requires'
@@ -172,6 +173,7 @@ class SQLServerAdapter < AbstractAdapter
172173
include Sqlserver::DatabaseStatements
173174
include Sqlserver::SchemaStatements
174175
include Sqlserver::DatabaseLimits
176+
include Sqlserver::QueryCache
175177
include Sqlserver::Errors
176178

177179
ADAPTER_NAME = 'SQLServer'.freeze

Diff for: test/cases/sqlserver_helper.rb

+2-2
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,10 @@ def method_added(method)
8282
end
8383

8484
ActiveRecord::ConnectionAdapters::SQLServerAdapter.class_eval do
85-
def raw_select_with_query_record(sql, name=nil, rows_only=false)
85+
def raw_select_with_query_record(sql, name=nil, options={})
8686
$queries_executed ||= []
8787
$queries_executed << sql unless IGNORED_SQL.any? { |r| sql =~ r }
88-
raw_select_without_query_record(sql,name,rows_only)
88+
raw_select_without_query_record(sql,name,options)
8989
end
9090
alias_method_chain :raw_select, :query_record
9191
end

Diff for: test/profile/connection.rb

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ def test_select
1717
end
1818
end
1919

20+
def test_select_one
21+
select_statement = "SELECT [topics].* FROM [topics]"
22+
ruby_profile :connection_select_one do
23+
3000.times { @connection.select_one(select_statement) }
24+
end
25+
end
26+
2027

2128
end
2229

0 commit comments

Comments
 (0)