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

Reply via email to