Package: libsqlite3-ruby1.8 Version: 1.1.0-2 Severity: normal Tags: patch
When using the prepare/execute/execute/... idiom with different variable bindings, sqlite3-ruby resets the statement handle between each execute call to ensure that old bindings are cleared and the new variables are bounded. However, if one wants use the same idiom by binding variables manually (calling Statment#bind_params with the varibles to bind, and Statement#execute with no variables) a few problems come up. First, Statment#bind_params doesn't reset the statment handle, so the variables are bounded improperly. Second, since the @results variable still contains the previous result set, the statement handle is reset during the execute call which eliminates previously bounded variables. As a result, the SQL statment executes with no bounded variables. The fix is to ensure that Statement#bind_params, Statement#bind_params, and Statement#execute all reset the statement handle immediately after a previous statement has been executed and before any new variables are bounded. Since Statement#bind_params calls bind_param internally, adding a check in Statement#bind_param is sufficient. I've included a patch that implements the desired behavior. For the record, this method of manual variable binding is used by the SQLite3 DBD driver to implement the prepare/execute idiom for DBI.
diff -uNr sqlite3-ruby-1.1.0.orig/lib/sqlite3/statement.rb sqlite3-ruby-1.1.0/lib/sqlite3/statement.rb --- sqlite3-ruby-1.1.0.orig/lib/sqlite3/statement.rb 2005-02-07 12:01:20.000000000 -0500 +++ sqlite3-ruby-1.1.0/lib/sqlite3/statement.rb 2007-01-04 18:08:29.278831832 -0500 @@ -115,6 +115,12 @@ # See also #bind_params. def bind_param( param, value ) must_be_open! + + if @results + @driver.reset( @handle ) + @results = nil + end + if Fixnum === param case value when Integer then