EV-ClickHouse

 view release on metacpan or  search on metacpan

t/28_pass2_coverage.t  view on Meta::CPAN

        host => $host, port => $nport, protocol => 'native',
        on_connect => sub {
            $ch->query("select a, b from _named28 order by a format TabSeparated", sub {
                my ($rows) = @_;
                is_deeply $rows, [[1, 'x'], [2, 'y'], [3, 'z']],
                    '  rows landed in declared column order';
                EV::break;
            });
        },
    );
    run_with_timeout(5);
    $ch->finish;
    $ch2->finish;
}

# for_table works on a named_rows connection (handles hashref result rows).
{
    my ($info, $err);
    my $ch; $ch = EV::ClickHouse->new(
        host => $host, port => $nport, protocol => 'native',
        named_rows => 1,
        on_connect => sub {
            $ch->query("create temporary table _ft28 (a UInt32, b String) engine = Memory", sub {
                $ch->for_table('_ft28', sub {
                    ($info, $err) = @_;
                    EV::break;
                });
            });
        },
        on_error => sub { $err = $_[0]; EV::break },
    );
    run_with_timeout(5);
    is $err, undef, 'for_table on named_rows connection succeeds';
    is_deeply [ map $_->{name}, @{ $info->{columns} } ],
              [ qw(a b) ],
              '  column names extracted from hashref rows';
    $ch->finish;
}

# max_recv_buffer tears the connection down with a clear error message
# when the response body would exceed the cap.
{
    my $err;
    my $ch; $ch = EV::ClickHouse->new(
        host => $host, port => $nport, protocol => 'native',
        max_recv_buffer => 4096,           # very small to force overflow
        on_connect => sub {
            $ch->query("select number from numbers(100000)",
                       { on_data => sub { } }, sub {
                (undef, $err) = @_;
                EV::break;
            });
        },
        on_error => sub { $err //= $_[0]; EV::break },
    );
    run_with_timeout(5);
    like $err, qr/recv buffer/i, 'max_recv_buffer tears down on overflow';
    eval { $ch->finish };
}

# max_recv_buffer also applies to chunked HTTP and gzip-decoded bodies
# (not only raw recv_buf). A small cap on a large select must error out.
SKIP: {
    skip 'HTTP not reachable', 1
        unless IO::Socket::INET->new(PeerAddr => $host, PeerPort => $hport, Timeout => 2);
    my $err;
    my $ch; $ch = EV::ClickHouse->new(
        host => $host, port => $hport, protocol => 'http',
        max_recv_buffer => 4096,
        on_connect => sub {
            $ch->query("select number from numbers(50000) format TabSeparated", sub {
                (undef, $err) = @_;
                EV::break;
            });
        },
        on_error => sub { $err //= $_[0]; EV::break },
    );
    run_with_timeout(5);
    like $err, qr/recv buffer|response too large/i,
         'max_recv_buffer caps HTTP responses too';
    eval { $ch->finish };
}

# http_basic_auth uses Authorization: Basic instead of X-ClickHouse-User/Key.
# We can't trivially inspect the wire but we can verify the connection
# still works when the option is on (server accepts both auth styles).
SKIP: {
    skip 'HTTP not reachable', 1
        unless IO::Socket::INET->new(PeerAddr => $host, PeerPort => $hport, Timeout => 2);
    my ($rows, $err);
    my $ch = EV::ClickHouse->new(
        host => $host, port => $hport, protocol => 'http',
        http_basic_auth => 1,
        on_connect => sub { },
        on_error => sub { $err = $_[0]; EV::break },
    );
    $ch->query("select 11 format TabSeparated", sub {
        ($rows, $err) = @_;
        EV::break;
    });
    run_with_timeout(5);
    is_deeply $rows, [[11]], 'http_basic_auth still authenticates correctly';
    $ch->finish;
}

# Per-query on_query_complete override REPLACES the connection-level
# hook for that one query (so per-call instrumentation doesn't double-
# count against global metrics).
{
    my @global; my @per_query;
    my $ch; $ch = EV::ClickHouse->new(
        host => $host, port => $nport, protocol => 'native',
        on_query_complete => sub { push @global, [@_] },
        on_connect => sub {
            $ch->query("select 1", sub { });    # global fires
            $ch->query("select 2",
                       { on_query_complete => sub { push @per_query, [@_] } },
                       sub { EV::break });
        },
    );
    run_with_timeout(5);



( run in 0.458 second using v1.01-cache-2.11-cpan-f4a522933cf )