atom feed23 messages in org.perl.dbi-devRe: AutoCommit and connect_cached()
FromSent OnAttachments
David WheelerJan 31, 2005 10:28 pm 
Tim BunceFeb 1, 2005 2:44 am 
David WheelerFeb 1, 2005 9:16 am 
Tim BunceFeb 2, 2005 2:59 am 
David WheelerFeb 2, 2005 10:50 am 
David WheelerFeb 2, 2005 10:58 am 
Tim BunceFeb 3, 2005 7:45 am 
David WheelerFeb 3, 2005 8:40 am 
Tim BunceFeb 3, 2005 3:30 pm 
David WheelerFeb 3, 2005 3:49 pm 
Tim BunceFeb 4, 2005 2:08 am 
David WheelerFeb 4, 2005 10:38 am 
Sheikin SergeiFeb 4, 2005 11:31 am 
Michael A ChaseFeb 4, 2005 12:22 pm 
David WheelerFeb 11, 2005 11:18 am 
Tim BunceFeb 12, 2005 10:11 am 
David WheelerFeb 12, 2005 4:35 pm 
Tim BunceFeb 13, 2005 2:44 pm 
David WheelerFeb 13, 2005 5:54 pm 
Tim BunceFeb 14, 2005 3:09 am 
David WheelerFeb 15, 2005 10:38 am 
Tim BunceFeb 15, 2005 2:22 pm 
David WheelerFeb 15, 2005 9:01 pm 
Subject:Re: AutoCommit and connect_cached()
From:David Wheeler (
Date:Feb 3, 2005 8:40:48 am

On Feb 3, 2005, at 7:45 AM, Tim Bunce wrote:

I must still be missing something...

Er, why?

Sorry, I kept forgetting that DBI::connect_cached() calls DBI::connect(), which calls DBI::_::dr::connect_cached(), which calls (if it finds no dbh in the cache) connect(). The part I kept missing was that connect() calls the driver connect_cached(), and therefore the attrs are reset by connect().

It's a circle of methods! :-)

I was just being vague to avoid having to explain how DBI->connect_cached calls DBI->connect in such a way that it knows it needs to call $drh->connect_cached instead of $drh->connect.

Oh, I see, and driver authors can implement their own connect_cached() methods, if need be.

Could be done in a driver subclass, but they're not well supported at the moment and probably more hassle than it's worth.

Yah. I was thinking of subclassing DBI::connect_cached(), when it's DBI::_::dr::connect_cached() that would need to be overridden in a subclass. Yeesh.

--- (revision 856) +++ (working copy) @@ -1403,6 +1403,7 @@ my $cache = $drh->FETCH('CachedKids'); $drh->STORE('CachedKids', $cache = {}) unless $cache;

+ my $no_reset = delete $attr->{NoReset}; my @attr_keys = $attr ? sort keys %$attr : (); my $key = do { local $^W; # silence undef warnings join "~~", $dsn, $user||'', $auth||'', $attr ? (@attr_keys,@{$attr}{@attr_keys}) : () @@ -1412,6 +1413,7 @@ # XXX warn if BegunWork? # XXX warn if $dbh->FETCH('AutoCommit') != $attr->{AutoCommit} ? # but that's just one (bad) case of a more general issue. + %$attr = () if $no_reset; return $dbh; } $dbh = $drh->connect(@_);

If this looks good to you, I can add a test for it and update the docs and send that patch.

Any thoughts on this, then?

In it says (slightly edited):

Rework handle creation to use methods: Maybe $h->new_child(\%handle_attr) dr::connect => $dbh = $drh->new_child(\%attr); $dbh->connect(...) - calls $dbh->reset() & db::prepare => sub ...::db::prepare { my ($dbh, $sql, $attr) = @_; $sth = $dbh->new_child($attr); $sth->prepare( $sql ) or return; return $sth; } sub prepare_cached - no change, calls $dbh->prepare. sub ...::st::prepare { $sth->reset; ... }

The key point is that attributes passed to $drh->connect and $dbh->prepare are applied to the new 'virgin' handle before the real $dbh->connect or $sth->prepare is called. (In case that's not clear, think about the $drh, $dbh, and $sth variables on those calls.)

I see. So if connect_cached() returns an existing handle, the attributes would not be applied to it, yes?

Thus expressions like $dbh->prepare("...", { RaiseError => 0 }) would then work as expected.

I'm not totally clear on why it wouldn't work as expected now. But it doesn't matter to me, at least, since I never pass attributes to prepare().

That's planned for DBI v2, but it seems DBI v2 isn't going to happen anytime soon so I'm wondering if it's something I should squeeze into DBI v1.

What's happened on the DBI v2 front?

You'd be most welcome to draw up an informal spec for some callbacks (such as OnConnect and OnConnectCached) for discussion and implementation.

Should be pretty straight-forward. Are there other events for which you'd like to add callbacks? OnPrepare, perhaps? OnExecute? OnFetch?