[sorry for the delay]

On Tue, Feb 15, 2005 at 10:32:52AM -0800, David Wheeler wrote:
> On Feb 14, 2005, at 3:14 AM, Tim Bunce wrote:
> 
> >In relation to connect_cached it boiled down to just the difference 
> >between:
> >
> >  if ($dbh and my $oc = $dbh->{OnConnect}) {
> >       $oc->($dbh, $dsn, $user, $pass, $attr) if ref $oc eq 'CODE';
> >  }
> >
> >and:
> >
> >  if (my $cb = $dbh->{Callbacks}) {
> >      my $oc = $cb->{"connect_cached.reused"};
> >      $oc->($dbh, $dsn, $user, $pass, $attr) if ref $oc eq 'CODE';
> >  }
> >
> >Not much in it really! :)
> 
> Oh, I see. So then Callbacks just becomes a hash reference of code 
> references, with each corresponding to a particular event. That is 
> cleaner. And easily done in Perl.

Yeap.

> >The rest of the $h->{Callbacks} infrastructure needn't be implemented
> >for just that bit. All it needs is for Callbacks to become a valid
> >DBI attribute.
> 
> Which is also pretty easily done, eh? Something like this?

Yes, though I wouldn't bother validating the contents of the hash.
Just checking you're getting a hash ref is enough I think.

> Please forgive my newbie XS coding. And yes, I know this doesn't compile. I 
> couldn't figure out where to declare Callbacks.

Pick another similar attribute, say CachedKids, and grep to see where/how
that's setup and used. Shout if you want more clues ;)

> -       # if the caller has provided a callback then call it
> -       # especially useful with connect_cached() XXX not 
> enabled/tested/documented
> -       if (0 and $dbh and my $oc = $dbh->{OnConnect}) { # XXX
> -           $oc->($dbh, $dsn, $user, $pass, $attr) if ref $oc eq 'CODE';
> +       # If the caller has provided a callback then call it
> +       if ($dbh and my $cb = $dbh->{Callbacks}{connect}) {
> +           $cb->($dbh, $dsn, $user, $pass, $attr);
>         }

The dispatcher (written in C) will handle the normal pre- and post-method 
callbacks,
so the explicit post-connect callback above wouldn't be needed in perl code.

If any method wants to have extra callbacks then it could define them to have
a "method.foo" name like connect_cached.reused here:

> +            # If the caller has provided a callback then call it
> +            if (my $cb = $dbh->{Callbacks}{"connect_cached.reused"}) {
> +                $cb->($dbh, $dsn, $user, $auth, $attr);
> +            }

Umm, it would be handy for the post-method callback to be able to access
the return value of the method (or at least the first value if it's a list).
I think temporarily aliasing $_ would cover that nicely.

Tim.

p.s. Don't forget tests, and then there's PurePerl support to consider...
Feel free to throw it back at me if it looks like too much work, or just
checkin bite sized pieces and see how it goes. Probably makes sense for
me to do at least the dispatcher changes.

Reply via email to