[Ruby-dbi-devel-new] BaseStatement#cancel default implementation

Erik Hollensbe erik at hollensbe.org
Thu Mar 20 09:58:02 EDT 2008

On Mar 19, 2008, at 9:41 PM, Mike Pomraning wrote:
> Proposal:  DBI::BaseStatement#cancel should simply read and discard
> any remaining rows, something like:
>    # class BaseStatement
>    # Discard all pending rows, if any, making the statement ready for
> re-execution.

I think this could be easily re-written as:

MUST Make the statement ready for re-execution. (using RFC parlance)

And lose nothing, leaving the concept of exhausting a cursor up to the  
driver if need be.

>    ...
>    # class StatementHandle
>    def execute(*args)
>       cancel if fetchable?  # <--- fetchability check is new
>       ...

I'm honestly not sure how to parse this. We especially don't want to  
cancel the statement if it's fetchable, did you mean to use 'unless'  
instead of 'if'?

> Having taken a crack at true (server-side) prepared statements in the
> Pg driver (Tracker "Patches" #18925), I started toying with a
> DatabaseHandle#prepare_cached(), ala "prepare_cached" from perl's
> DBI.pm.

I don't want to distract you from improving DBI at all, but I have no  
intention of adding features like this in this release. Right now my  
concern is to get the existing features into an easily maintainable  
and implementable state, which is why type handling is at the top of  
my list. Anyone who's read the guts of a DBD should be able to  
understand why I'm tackling this first.

I'm not saying that a fully specced, fully implemented across all DBDs  
and DBI implementation won't be considered, it's just that I'm not  
ready to discuss it yet, but I will offer my viewpoints for now.

> Now, DBI.pm raises the question of what to do when a #fetchable? sth
> (DBI.pm analog: $sth->{Active}) is pulled from the cache.  DBI.pm by
> default complains about this situation, but resets the sth with
> $sth->finish, and moves on.  We can't simply imitate that behavior,
> since our #finish is more like the DBI.pm's $sth->DESTROY.  Our
> #cancel comes closest, however, to a bona fide prepared statement
> reset.
> Reactions?  There's still the separate question of what
> safety-checking #prepare_cached might look like, e.g.:
>   dbh.prepare_cached(sql, :if_active => ACTIVE_HANDLE_WARN) #
> default, complain but cancel() the cached sth
>   # ACTIVE_HANDLE_CANCEL ... silently cancel() the cached sth
>   # ACTIVE_HANDLE_IGNORE ... don't bother checking cached sth for
> fetchable?ness
>   # ACTIVE_HANDLE_REPLACE ... cache a newly prepared sth instead,
> without mutating the old one in any way

Initially peeking at this it seems like we've got a situation where  
constants are used to define actions on a specific set of states.

Instead of just giving them four options, why not give them a series  
of state reporting methods (e.g., cancelled? which would report if if  
the statement was cancelled prior to a new execution) and let them  
work with it themselves, and allow the option of being able to finish  
cached statements after retrieving them.



More information about the Ruby-dbi-devel-new mailing list