package DBIx::Fast::Result;

use v5.38;
use Object::Pad;

class DBIx::Fast::Result {

  field $sth   :param :reader;
  field $count :reader = 0;

  method hash () {
    my $row = $sth->fetchrow_hashref;
    $count++ if $row;
    return $row;
  }
  
  method array () {
    my @row = $sth->fetchrow_array;
    return unless @row;
    $count++;
    return \@row;
  }
  
  method all () {
    my $rows = $sth->fetchall_arrayref({});
    $count += scalar @$rows;
    return $rows;
  }
  
  method flat () {
    # fetchall_arrayref([0]) loops in DBI's C path - much faster than a
    # per-row Perl fetch on large result sets.
    my $col = $sth->fetchall_arrayref([0]);
    $count += scalar @$col;
    return [ map { $_->[0] } @$col ];
  }
  
  method finish () {
    $sth->finish if $sth && $sth->{Active};
  }
  
  method DESTROY () {
    $self->finish;
  }

}

1;

__END__

=head1 NAME

DBIx::Fast::Result - Lightweight row iterator for query results

=head1 SYNOPSIS

    my $rs = $db->query('SELECT id, name FROM users WHERE active = ?', 1);

    while (my $row = $rs->hash) {
        say "$row->{id}: $row->{name}";
    }

    # Or fetch remaining rows at once
    my $rs2 = $db->query('SELECT id FROM products LIMIT 100');
    my $all = $rs2->all;

    # Or as a flat list of single-column values
    my $rs3 = $db->query('SELECT email FROM users');
    my $emails = $rs3->flat;

=head1 DESCRIPTION

A thin wrapper around a DBI statement handle that provides convenient
iterator methods. Created by L<DBIx::Fast::SQL/query> and automatically
finishes the statement handle when the object goes out of scope.

=head1 METHODS

=head2 hash

    while (my $row = $rs->hash) { ... }

Returns the next row as a hashref, or C<undef> when exhausted.

=head2 array

    while (my $row = $rs->array) { ... }

Returns the next row as an arrayref, or C<undef> when exhausted.

=head2 all

    my $rows = $rs->all;

Returns all remaining rows as an arrayref of hashrefs.

=head2 flat

    my $vals = $rs->flat;

Returns all remaining values from the first column as an arrayref.

=head2 count

    my $n = $rs->count;

Returns the number of rows fetched so far.

=head2 finish

    $rs->finish;

Explicitly finishes the statement handle. Called automatically on
object destruction.

=head1 AUTHOR

SeHarrys

=head1 LICENSE

This is free software under the Artistic License 2.0.

=cut
