Hi Steven.
Did you mean to post this to dbi2-dev?
I've redirected it to [EMAIL PROTECTED]
On Tue, Jan 24, 2006 at 04:27:46PM -0500, Steven Lembark wrote:
>
> DBI-1.50 uses a technique with HandleError that allows the
> handler to update or zero the error message and insert any
> data it wants to into the return. The HandleError sub
> can currently return false to indicate that DBI should
> follow the normal error procedure or true to just return
> the update data content and ignore the error.
>
> The main problem with this approach is that even in cases
> where the handler can deal with the error (e.g., reconnecting
> the database handle) it is difficult to redispatch the
> original request. The handler can put a sentinel value into
> the returned data to indicate that the caller should re-
> attempt the DBI operation, but this is messy at best.
The current true/false return value of the handler can be extended...
> There is also the limitation that even where the handler
> can fix the problem, it can only return one value, which
> leaves it unable to resolve fetch*_array and fetch*_hash
> calls by itself.
The HandleError could return an array ref which would indicate that the
contents of the array should be used as the return value of the original call.
Which is what I think you're saying at the end below.
(The handler also needs to be called in the same scalar/list context as
the original method. Or some other way added to pass that info to the handler.)
> A better approach might be allowing the error handler
> to signal DBI that it should re-dispatch the original
> request and return the result. This could be signalled
> via three-state logic in the ErrorHandler's return
> value or exporting a "redispatch" method that the
> handler could use for itself.
>
> Tristate logic would use undef, false, or true to
> distinguish between reporting the error, ignoring
> the error without redispatch (what true does now),
> or redispatching the request (not avaiable now).
undef - redispatch
false - raise error etc
array ref - return values contained in array
other true - return as now
> The redispatch method would require some additional
> bookkeeping on DBI's part: storing the last method
> and its arguments. Some of this is already done
> in DBI-1.50 and the amount of it is small enough
> that it should not be a major problem.
>
> In this case the fixup handler could fix the problem
> (say, re-connecting a new handle and replaceing the
> existing one with the new one) then call:
> $dbh->redispatch;
> to replay whatever caused the error.
>
> Becuase this would be done within the fixup handler,
> it could more easily avoid infinte loops (by croaking
> if it gets back an error from the re-dispatch) or
> signal true to have the redispatched values handed
> back to the caller.
I'd rather the changes to HandleError were implemented
without redispatch for now. Then gain some experience
with that before reconsidering redispatch.
HandleError could have enough info to redispatch by itself:
@foo = (wantarray) ? $h->$method(@args) : scalar $h->$method(@args)
it just needs @args and the correct context. Both easily added.
Patches (with tests naturally :-) most welcome - through probably best
to plan it in more detail first to help smooth the way.
Tim.
> A small change in the handling of the input arguments
> would simplify this also. In DBI-1.50, the HandleError
> sub gets a single value to play with. If this were an
> arrayref then the fixup handlers could replace them
> with the full return value handed back to the caller.
> An alternative would be passing in a scalar ref which
> could then be updated with whatever the handler wants
> returned, it could then be de-referenced in the DBI
> error layer to get a return.
>
> These could easily be combined in the DBI error
> handler with something like:
>
> # dbi layer calls handler
>
> # syntatic sugar. call order looks more like
> # what OO people expect: the object first.
>
> my $handler = $dbi->{HandleError};
>
> if( my $user_data = $dbh->$handler( $message, $user_data ) )
> {
> # caller gets the expanded return value back,
> # which allows for passing anything back.
>
> @$user_data;
> }
> elsif( defined $a )
> {
> # redispatch the original call with its original
> # arguments.
>
> $dbh->redispatch;
> }
> else
> {
> # continue as usual
>
> die;
> }
>
>
>
>
> --
> Steven Lembark 85-09 90th Street
> Workhorse Computing Woodhaven, NY 11421
> [EMAIL PROTECTED] 1 888 359 3508