Description
I just added support for using mysql2 0.4+ native prepared statements to Sequel (jeremyevans/sequel@5066f16). Based on my experiences with it, I think improvements to the API would be beneficial.
In the general API to send queries to the server (Client#query
), you can specify options on a per-query basis. However, the prepared statements API doesn't appear to support that. Client#prepare
only takes the sql, not an options hash, and Statement#execute
only takes arguments, not an options hash. Statement
gets the query options to use by copying the Client
's query options inside of Statement#execute
. Result
stores the query options in an instance variable, but does not offer a method to access them.
To work around this issue, you need to modify the Client
's query options before calling Statement#execute
, then reset the Client
's query options after. This is what Sequel does in order to make sure that the behavior for prepared statements matches the behavior for non-prepared statements in regards to which options are set.
The other possible way to work around this is to modify the query options in the Result
, but that has issues:
- It's ugly (
result.instance_variable_get(:@query_options).merge!(options)
) - It causes warnings in
Result#initialize
if theClient
doesn't have:cache_rows=>true
(https://github.com/brianmario/mysql2/blob/master/ext/mysql2/result.c#L890) - It can't handle streaming, since that happens before the
Result
is created (https://github.com/brianmario/mysql2/blob/master/ext/mysql2/statement.c#L366-L370)
I think the best way to fix this would be to copy the Client
's query options to the Statement
in Statement#initialize
, and add Statement#query_options
. Alternatively, you could add a Statement#execute_with_options
method that accepted an options hash and merged it into the Client
's query options.