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:43 am 
David WheelerFeb 1, 2005 9:16 am 
Tim BunceFeb 2, 2005 2:58 am 
David WheelerFeb 2, 2005 10:49 am 
David WheelerFeb 2, 2005 10:57 am 
Tim BunceFeb 3, 2005 7:44 am 
David WheelerFeb 3, 2005 8:40 am 
Tim BunceFeb 3, 2005 3:30 pm 
David WheelerFeb 3, 2005 3:48 pm 
Tim BunceFeb 4, 2005 2:07 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:37 am 
Tim BunceFeb 15, 2005 2:21 pm 
David WheelerFeb 15, 2005 9:01 pm 
Subject:Re: AutoCommit and connect_cached()
From:Tim Bunce (Tim.@pobox.com)
Date:Feb 3, 2005 7:44:51 am
List:org.perl.dbi-dev

On Wed, Feb 02, 2005 at 10:50:20AM -0800, David Wheeler wrote:

On Feb 2, 2005, at 2:59 AM, Tim Bunce wrote:

Ah, I see. But loking at DBI::_::dr::connect_cached, it looks as though connect() isn't called if it finds an active, pingable driver in the cache.

That's right.

I must still be missing something...

Er, why?

Note that drivers have the opportunity to apply %$attr themselves during their own connect call and deleted those applied attributes from %$attr so the DBI won't have any left to apply.

Uh, "their own connect call"? Can you tell me more about what this means?

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.

I'd love to be able to remove attributes before the call to connect() if the driver already exists. Would I have to override connect_cached() in a subclass, perhaps?

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

--- DBI.pm (revision 856) +++ DBI.pm (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.

At this point I'm undecided about supporting something like a NoReset attribute - but mainly because it would probably become the default behaviour if I make other changes to handle creation that I'm thinking of.

Oh? Such as...?

In http://search.cpan.org/src/TIMB/DBI/ToDo 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.)

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

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.

Also, it may be possible to get the same effect by adding more general callback hooks:

$dbh = DBI->connect_cached(..., { OnConnect => sub { print "New connection" }; OnConnectCached => sub { print "Old connection"; my (...,$attr)=@_; %$attr = () }; });

Ooh, is that documented?

Only vagely in the ToDo/Roadmap files.

I only see OnConnect at line 655 (in svn). But yeah, if there was an OnConnectCached (which, I assume, would only be called if it found a handle in the cache), then it would indeed do the trick.

Yeap.

Still, it's too late for 1.47 now.

Just let me know how you'd like to proceed with these issues in 1.48 and I'll do what i can to help (such as with the NoReset patch).

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

Tim.