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 )