summaryrefslogtreecommitdiff
path: root/t/72childhandles.t
diff options
context:
space:
mode:
Diffstat (limited to 't/72childhandles.t')
-rw-r--r--t/72childhandles.t149
1 files changed, 149 insertions, 0 deletions
diff --git a/t/72childhandles.t b/t/72childhandles.t
new file mode 100644
index 0000000..48fbe37
--- /dev/null
+++ b/t/72childhandles.t
@@ -0,0 +1,149 @@
+#!perl -w
+$|=1;
+
+use strict;
+
+#
+# test script for the ChildHandles attribute
+#
+
+use DBI;
+
+use Test::More;
+
+my $HAS_WEAKEN = eval {
+ require Scalar::Util;
+ # this will croak() if this Scalar::Util doesn't have a working weaken().
+ Scalar::Util::weaken( my $test = [] ); # same test as in DBI.pm
+ 1;
+};
+if (!$HAS_WEAKEN) {
+ chomp $@;
+ print "1..0 # Skipped: Scalar::Util::weaken not available ($@)\n";
+ exit 0;
+}
+
+plan tests => 16;
+
+my $using_dbd_gofer = ($ENV{DBI_AUTOPROXY}||'') =~ /^dbi:Gofer.*transport=/i;
+
+my $drh;
+
+{
+ # make 10 connections
+ my @dbh;
+ for (1 .. 10) {
+ my $dbh = DBI->connect("dbi:ExampleP:", '', '', { RaiseError=>1 });
+ push @dbh, $dbh;
+ }
+
+ # get the driver handle
+ $drh = $dbh[0]->{Driver};
+ ok $drh;
+
+ # get the kids, should be the same list of connections
+ my $db_handles = $drh->{ChildHandles};
+ is ref $db_handles, 'ARRAY';
+ is scalar @$db_handles, scalar @dbh;
+
+ # make sure all the handles are there
+ my $found = 0;
+ foreach my $h (@dbh) {
+ ++$found if grep { $h == $_ } @$db_handles;
+ }
+ is $found, scalar @dbh;
+}
+
+# now all the out-of-scope DB handles should be gone
+{
+ my $handles = $drh->{ChildHandles};
+ my @db_handles = grep { defined } @$handles;
+ is scalar @db_handles, 0, "All handles should be undef now";
+}
+
+my $dbh = DBI->connect("dbi:ExampleP:", '', '', { RaiseError=>1 });
+
+my $empty = $dbh->{ChildHandles};
+is_deeply $empty, [], "ChildHandles should be an array-ref if wekref is available";
+
+# test child handles for statement handles
+{
+ my @sth;
+ my $sth_count = 20;
+ for (1 .. $sth_count) {
+ my $sth = $dbh->prepare('SELECT name FROM t');
+ push @sth, $sth;
+ }
+ my $handles = $dbh->{ChildHandles};
+ is scalar @$handles, scalar @sth;
+
+ # test a recursive walk like the one in the docs
+ my @lines;
+ sub show_child_handles {
+ my ($h, $level) = @_;
+ $level ||= 0;
+ push(@lines,
+ sprintf "%sh %s %s\n", $h->{Type}, "\t" x $level, $h);
+ show_child_handles($_, $level + 1)
+ for (grep { defined } @{$h->{ChildHandles}});
+ }
+ my $drh = $dbh->{Driver};
+ show_child_handles($drh, 0);
+ print @lines[0..4];
+
+ is scalar @lines, $sth_count + 2;
+ like $lines[0], qr/^drh/;
+ like $lines[1], qr/^dbh/;
+ like $lines[2], qr/^sth/;
+}
+
+my $handles = $dbh->{ChildHandles};
+my @live = grep { defined $_ } @$handles;
+is scalar @live, 0, "handles should be gone now";
+
+# test visit_child_handles
+{
+ my $info;
+ my $visitor = sub {
+ my ($h, $info) = @_;
+ my $type = $h->{Type};
+ ++$info->{ $type }{ ($type eq 'st') ? $h->{Statement} : $h->{Name} };
+ return $info;
+ };
+ DBI->visit_handles($visitor, $info = {});
+ is_deeply $info, {
+ 'dr' => {
+ 'ExampleP' => 1,
+ ($using_dbd_gofer) ? (Gofer => 1) : ()
+ },
+ 'db' => { '' => 1 },
+ };
+
+ my $sth1 = $dbh->prepare('SELECT name FROM t');
+ my $sth2 = $dbh->prepare('SELECT name FROM t');
+ DBI->visit_handles($visitor, $info = {});
+ is_deeply $info, {
+ 'dr' => {
+ 'ExampleP' => 1,
+ ($using_dbd_gofer) ? (Gofer => 1) : ()
+ },
+ 'db' => { '' => 1 },
+ 'st' => { 'SELECT name FROM t' => 2 }
+ };
+
+}
+
+# test that the childhandle array does not grow uncontrollably
+SKIP: {
+ skip "slow tests avoided when using DBD::Gofer", 2 if $using_dbd_gofer;
+
+ for (1 .. 1000) {
+ my $sth = $dbh->prepare('SELECT name FROM t');
+ }
+ my $handles = $dbh->{ChildHandles};
+ cmp_ok scalar @$handles, '<', 1000;
+ my @live = grep { defined } @$handles;
+ is scalar @live, 0;
+}
+
+1;