EV-Pg

 view release on metacpan or  search on metacpan

t/05_leak.t  view on Meta::CPAN

                $destroyed = 1;
                EV::break;
            });
        },
        on_error => sub { EV::break },
    );
    my $t = EV::timer(5, 0, sub { EV::break });
    EV::run;
    ok($destroyed, 'destroyed inside query callback without crash');
}

# Test handler cleanup (set and unset)
{
    my $pg = EV::Pg->new(on_error => sub {});
    my $called = 0;
    $pg->on_connect(sub { $called++ });
    $pg->on_notify(sub { $called++ });
    $pg->on_notice(sub { $called++ });
    # Clear handlers
    $pg->on_connect(undef);
    $pg->on_notify(undef);
    $pg->on_notice(undef);
    ok(1, 'handler set/unset without leak');
}

# Test finish with pending callbacks
{
    my $pg;
    my $err_count = 0;
    $pg = EV::Pg->new(
        conninfo   => $conninfo,
        on_connect => sub {
            $pg->query("select pg_sleep(10)", sub {
                my ($rows, $err) = @_;
                $err_count++ if $err;
            });
            $pg->finish;
            EV::break;
        },
        on_error => sub { EV::break },
    );
    my $t = EV::timer(5, 0, sub { EV::break });
    EV::run;
    ok($err_count == 1, 'finish cancels pending callbacks cleanly');
}

# LISTEN / NOTIFY round-trip with handler set/unset
{
    my $got = 0;
    my $pg;
    $pg = EV::Pg->new(
        conninfo   => $conninfo,
        on_notify  => sub { $got++; EV::break },
        on_connect => sub {
            $pg->query("listen leak_chan", sub {
                $pg->query("notify leak_chan, 'payload'", sub {});
            });
        },
        on_error => sub { diag "err: $_[0]"; EV::break },
    );
    $pg->keep_alive(1);
    my $t = EV::timer(5, 0, sub { EV::break });
    EV::run;
    $pg->on_notify(undef);  # release handler before destroy
    ok($got >= 1, 'notify round-trip without leak');
}

# Notice receiver: reset role with a notice-emitting plpgsql block
{
    my $pg;
    my $notices = 0;
    $pg = EV::Pg->new(
        conninfo   => $conninfo,
        on_notice  => sub { $notices++ },
        on_connect => sub {
            $pg->query("do \$\$ begin raise notice 'hi'; end \$\$", sub {
                EV::break;
            });
        },
        on_error => sub { EV::break },
    );
    my $t = EV::timer(5, 0, sub { EV::break });
    EV::run;
    ok($notices >= 1, 'notice receiver fired without leak');
}

# COPY IN cycle
{
    my $pg;
    my $copied;
    $pg = EV::Pg->new(
        conninfo   => $conninfo,
        on_connect => sub {
            $pg->query("create temp table leak_t (n int)", sub {
                $pg->query("copy leak_t from stdin", sub {
                    my ($d, $e) = @_;
                    if (defined $d && $d eq 'COPY_IN') {
                        $pg->put_copy_data("1\n");
                        $pg->put_copy_data("2\n");
                        $pg->put_copy_end;
                        return;
                    }
                    $copied = $d;
                    EV::break;
                });
            });
        },
        on_error => sub { diag "err: $_[0]"; EV::break },
    );
    my $t = EV::timer(5, 0, sub { EV::break });
    EV::run;
    is($copied, '2', 'COPY IN cycle without leak');
}

# COPY OUT cycle
{
    my $pg;
    my $finished = 0;
    $pg = EV::Pg->new(
        conninfo   => $conninfo,
        on_connect => sub {



( run in 1.067 second using v1.01-cache-2.11-cpan-e86d8f7595a )