Skip to content

Commit

Permalink
Allow adapter to return multipe results sets, for example from stored…
Browse files Browse the repository at this point in the history
… procedures. Fixes issue #29.
  • Loading branch information
metaskills committed Apr 20, 2010
1 parent 0368093 commit da13293
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 12 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@

MASTER

* Allow adapter to return multipe results sets, for example from stored procedures. [Chris Hall]


* 2.3.4

Expand Down
40 changes: 28 additions & 12 deletions lib/active_record/connection_adapters/sqlserver_adapter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ def run_with_isolation_level(isolation_level)
end

def select_rows(sql, name = nil)
raw_select(sql,name).last
raw_select(sql,name).first.last
end

def execute(sql, name = nil, &block)
Expand All @@ -410,7 +410,11 @@ def execute_procedure(proc_name, *variables)
vars = variables.map{ |v| quote(v) }.join(', ')
sql = "EXEC #{proc_name} #{vars}".strip
select(sql,'Execute Procedure',true).inject([]) do |results,row|
results << row.with_indifferent_access
if row.kind_of?(Array)
results << row.inject([]) { |rs,r| rs << r.with_indifferent_access }
else
results << row.with_indifferent_access
end
end
end

Expand Down Expand Up @@ -824,7 +828,15 @@ def auto_reconnected?

def select(sql, name = nil, ignore_special_columns = false)
repair_special_columns(sql) unless ignore_special_columns
fields, rows = raw_select(sql,name)
fields_and_row_sets = raw_select(sql,name)
final_result_set = fields_and_row_sets.inject([]) do |rs,fields_and_rows|
fields, rows = fields_and_rows
rs << zip_fields_and_rows(fields,rows)
end
final_result_set.many? ? final_result_set : final_result_set.first
end

def zip_fields_and_rows(fields, rows)
rows.inject([]) do |results,row|
row_hash = {}
fields.each_with_index do |f, i|
Expand Down Expand Up @@ -859,24 +871,28 @@ def do_execute(sql,name=nil)

def raw_select(sql, name = nil)
handle = raw_execute(sql,name)
fields = handle.columns(true).map{|c|c.name}
results = handle_as_array(handle)
rows = results.inject([]) do |rows,row|
row.each_with_index do |value, i|
if value.is_a? ODBC::TimeStamp
row[i] = value.to_sqlserver_string
fields_and_row_sets = []
loop do
fields = handle.columns(true).map{|c|c.name}
results = handle_as_array(handle)
rows = results.inject([]) do |rows,row|
row.each_with_index do |value, i|
if value.is_a? ODBC::TimeStamp
row[i] = value.to_sqlserver_string
end
end
rows << row
end
rows << row
fields_and_row_sets << [fields,rows]
finish_statement_handle(handle) && break unless handle.more_results
end
return fields, rows
fields_and_row_sets
end

def handle_as_array(handle)
array = handle.inject([]) do |rows,row|
rows << row.inject([]){ |values,value| values << value }
end
finish_statement_handle(handle)
array
end

Expand Down
11 changes: 11 additions & 0 deletions test/cases/execute_procedure_test_sqlserver.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,16 @@ def setup
end if sqlserver_2000?
end

should 'allow multiple result sets to be returned' do
results1, results2 = @klass.execute_procedure('sp_helpconstraint','accounts')
assert_instance_of Array, results1
assert_instance_of HashWithIndifferentAccess, results1.first
assert results1.first['Object Name']
assert_instance_of Array, results2
assert_instance_of HashWithIndifferentAccess, results2.first
assert results2.first['constraint_name']
assert results2.first['constraint_type']
end


end

0 comments on commit da13293

Please sign in to comment.