Isaac Rabinovitch
Isaac Rabinovitch

Reputation: 536

Ruby's dbi select_all gives funny results when you ask for an array

Consider this program

require 'dbi'

handle = DBI.connect('DBI:Mysql:tasks', 'root', 'stupid')

handle.select_all('select * from tasks') do |row|
  puts row.inspect
end

rows = handle.select_all('select * from tasks')
puts rows.inspect

The first call to select_all is passed a block, which it uses to iterate through the table rows, just as it's suppose to. That's the standard Ruby idiom for iteration, so of course it works.

The second call should return the same data, but all at once, packaged in an array. What the array actually contains is the last row of the table over and over!

Is this a bug, or am I doing something wrong?

Upvotes: 0

Views: 546

Answers (2)

Russell Fulton
Russell Fulton

Reputation: 11

I just stumbled across this too. After considerable research I have decided that every instance of DBI::Row associated with a particular statement hand reference the same memory. Worse still dup or cloning it makes no difference. The only way to get a proper copy is to convert it to an array with .to_a which means you loose the methods :(

I took the trouble to file a bug report on rubyforge -- not because I think it will get fixed but because it may help some other sucker who is pulling their hair out.

In fact I have just finished converting a couple of scripts over to Sequel from DBI. Sequel looks very nice as it allow both ORM type access as well as supporting raw sql like dbi.

Translation was straight forward.

Upvotes: 0

Russell Fulton
Russell Fulton

Reputation: 11

I just stumbled across this too. After considerable research I have decided that every instance of DBI::Row associated with a particular statement hand reference the same memory. Worse still dup or cloning it makes no difference. The only way to get a proper copy is to convert it to an array with .to_a which means you lose the methods :(

I took the trouble to file a bug report on rubyforge -- not because I think it will get fixed but because it may help some other sucker who is pulling their hair out.

Upvotes: 1

Related Questions