| From | Sent On | Attachments |
|---|---|---|
| David Wheeler | Jan 31, 2005 10:28 pm | |
| Tim Bunce | Feb 1, 2005 2:43 am | |
| David Wheeler | Feb 1, 2005 9:16 am | |
| Tim Bunce | Feb 2, 2005 2:58 am | |
| David Wheeler | Feb 2, 2005 10:49 am | |
| David Wheeler | Feb 2, 2005 10:57 am | |
| Tim Bunce | Feb 3, 2005 7:44 am | |
| David Wheeler | Feb 3, 2005 8:40 am | |
| Tim Bunce | Feb 3, 2005 3:30 pm | |
| David Wheeler | Feb 3, 2005 3:48 pm | |
| Tim Bunce | Feb 4, 2005 2:07 am | |
| David Wheeler | Feb 4, 2005 10:38 am | |
| Sheikin Sergei | Feb 4, 2005 11:31 am | |
| Michael A Chase | Feb 4, 2005 12:22 pm | |
| David Wheeler | Feb 11, 2005 11:18 am | |
| Tim Bunce | Feb 12, 2005 10:11 am | |
| David Wheeler | Feb 12, 2005 4:35 pm | |
| Tim Bunce | Feb 13, 2005 2:44 pm | |
| David Wheeler | Feb 13, 2005 5:54 pm | |
| Tim Bunce | Feb 14, 2005 3:09 am | |
| David Wheeler | Feb 15, 2005 10:37 am | |
| Tim Bunce | Feb 15, 2005 2:21 pm | |
| David Wheeler | Feb 15, 2005 9:01 pm |
| Subject: | Callbacks | |
|---|---|---|
| From: | Tim Bunce (Tim....@pobox.com) | |
| Date: | Feb 4, 2005 2:07:42 am | |
| List: | org.perl.dbi-dev | |
On Thu, Feb 03, 2005 at 03:49:11PM -0800, David Wheeler wrote:
On Feb 3, 2005, at 3:30 PM, Tim Bunce wrote:
Should be pretty straight-forward. Are there other events for which you'd like to add callbacks? OnPrepare, perhaps? OnExecute? OnFetch?
Yes, but let's just start with the connect ones for now.
Okay. It seems pretty simple. Your initial implementation is quite straight-forward:
if ($dbh and my $oc = $dbh->{OnConnect}) { $oc->($dbh, $dsn, $user, $pass, $attr) if ref $oc eq 'CODE'; }
The only issue I can think of is that some callbacks will be called much more than others. Do you think that it's a performance issue to be checking for a callback every time the method is called when most people won't use it at all? I don't think I see a way around that, though...
One way I'd had in the back of my mind way to use the DBI dispatcher to fire the callbacks.
$h->{Callbacks}->{$method_name} = \&foo; # called on entry
$h->{Callbacks}->{$method_name} = [ \&foo, \&bar ]; # foo on entry, bar on
exit
$h->{Callbacks}->{$method_name} = [ \@subrefs, \&bar ]; # each of @subrefs on
entry, bar on exit
that way _every_ method would get pre and post call hooks for free. If a handle has no callbacks the cost would be unmeasurable (just a bit flag test in the dispatcher). If a handle has any callbacks then the added cost for calling a method that doesn't have a callback would just be one hash lookup.
How's your C coding? :)
This approach doesn't directly support callbacks that need to fire _within_ a method, such as the proposed OnConnectCached firing only if connect_cached() does _not_ need to call connect().
[For that case you could have an pre-connect_cached callback that temporarily installs a connect callback which sets a flag, and a post-connect_cached callback that resets %$attr if the flag's not set. But that's getting quite baroque!]
Alternatively connect_cached() could call a new method in that situation and the hooks could be applied to that. But that's relatively expensive and it would be 'odd' for that method to be called with the $attr that was passed to connect_cached().
Alternatively some pseudo-method-names could be supported in the $h->{Callbacks} hash (ie "connect_cached.reused") and the relevant methods could check for and call them directly. Then the extra code in connect_cached would something like this:
if (my $cb = $dbh->{Callbacks}) { my $oc = $cb->{"connect_cached.reused"}; $oc->($dbh, $dsn, $user, $pass, $attr) if ref $oc eq 'CODE'; }
Umm, food for thought...
Tim.





