EV-ClickHouse

 view release on metacpan or  search on metacpan

t/11_new_features.t  view on Meta::CPAN

                });
            });
        });
    },
);

# Test 15-17: named_rows (results as hashrefs)
with_native(
    named_rows => 1,
    tests      => 3,
    cb         => sub {
        $ch->query("select 42 as a, 'hi' as b", sub {
            my ($rows, $err) = @_;
            ok(!$err, 'named_rows: no error');
            is(ref $rows->[0], 'HASH', 'named_rows: row is hashref');
            is_deeply($rows->[0], { a => 42, b => 'hi' }, 'named_rows: correct keys/values');
            EV::break;
        });
    },
);

# Test 18-19: on_disconnect callback (native)
with_native(
    tests => 2,
    cb    => sub {
        ok($ch->is_connected, 'on_disconnect: connected');
        my $disconnected = 0;
        $ch->on_disconnect(sub { $disconnected = 1 });
        $ch->finish;
        ok($disconnected, 'on_disconnect: callback fired');
        EV::break;
    },
);

# Test 20-21: on_disconnect callback (HTTP)
with_http(
    tests => 2,
    cb    => sub {
        ok($ch->is_connected, 'on_disconnect HTTP: connected');
        my $disconnected = 0;
        $ch->on_disconnect(sub { $disconnected = 1 });
        $ch->finish;
        ok($disconnected, 'on_disconnect HTTP: callback fired');
        EV::break;
    },
);

# Test 22-23: error code in error messages (native)
with_native(
    tests => 2,
    cb    => sub {
        $ch->query("select nonexistent_column from system.one", sub {
            my ($rows, $err) = @_;
            ok($err, 'error_code: got error');
            like($err, qr/Code: \d+/, 'error_code: contains Code: N');
            EV::break;
        });
    },
);

# Test 24-26: streaming on_data callback (native)
with_native(
    tests => 3,
    cb    => sub {
        my @blocks;
        $ch->query(
            "select number from numbers(100)",
            { on_data => sub { push @blocks, $_[0] } },
            sub {
                my ($rows, $err) = @_;
                ok(!$err, 'on_data: no error');
                ok(@blocks >= 1, "on_data: received " . scalar(@blocks) . " block(s)");
                # Final callback should have empty/undef rows since on_data consumed them
                my $total = 0;
                $total += scalar @$_ for @blocks;
                is($total, 100, 'on_data: total 100 rows across blocks');
                EV::break;
            },
        );
    },
);

# Test 27-28: query_timeout (should timeout on a long query)
with_native(
    tests => 2,
    cb    => sub {
        $ch->query(
            "select sleep(3)",
            { query_timeout => 1 },
            sub {
                my ($rows, $err) = @_;
                ok($err, 'query_timeout: got error');
                like($err, qr/timeout/i, 'query_timeout: error mentions timeout');
                EV::break;
            },
        );
    },
);

# Test 29-30: cancel (native)
with_native(
    tests => 2,
    cb    => sub {
        $ch->query("select count() from system.numbers limit 1", sub {
            my ($rows, $err) = @_;
            ok($err, 'cancel: got error');
            ok(1, 'cancel: callback delivered');
            EV::break;
        });
        # cancel after a short delay
        my $t = EV::timer(0.5, 0, sub {
            $ch->cancel;
        });
    },
);



( run in 1.954 second using v1.01-cache-2.11-cpan-0d23b851a93 )