summaryrefslogtreecommitdiff
path: root/t/72childhandles.t
blob: 48fbe37b3967bf7f100a869abc75d5c52d00e142 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
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;