Here is my sample code for using DBI:
dbh = DBI.connect(\"DBI:Mysql:host=#{server};database=mysql\", user, pass)
rows = dbh.select_all(\"SHOW TABLES\")
I guess that dbh.select_all
returns an instance of Enumerator, which yields the same row on each iteration. See this pseudocode to understand what I mean:
def select_all(query)
db_row = Row.new
reader = @connection.execute_reader(query)
Enumerator.new do |yielder|
until reader.end?
db_row.populate_from(reader)
yielder.yield db_row
reader.next!
end
end
end
Thus, if you're using select_all without block, an Enumerator will be returned, which basically yields the same db_row object.
This is just a guess, but, I believe the truth is nearby.
The source code fetch
method definition says that I was wrong, because @row
is dup
licated on each iteration. Well, probably the error is somewhere up the stack.
The same is also happenning when I query an MS SQL DB using DBI.connect("DBI:ODBC:Driver={SQL Server};...")
My work around was to forcably convert the DBI::Row to an array:
sth = dbh.execute "..."
begin
return sth.map{ |row| row.to_a }
ensure
sth.finish
end
I'll bet $1,000 that the issue is to do with buffer reuse - a possible 'performance' enhancement that has had underirable side effects!