package Mojo::Pg::Results; use Mojo::Base -base; use Mojo::Collection; use Mojo::JSON qw(from_json); use Mojo::Util qw(tablify); has [qw(db sth)]; sub DESTROY { my $self = shift; return unless my $sth = $self->{sth}; $sth->finish unless --$sth->{private_mojo_results}; } sub array { ($_[0]->_expand($_[0]->sth->fetchrow_arrayref))[0] } sub arrays { _collect($_[0]->_expand(@{$_[0]->sth->fetchall_arrayref})) } sub columns { shift->sth->{NAME} } sub hash { ($_[0]->_expand($_[0]->sth->fetchrow_hashref))[0] } sub expand { ++$_[0]{expand} and return $_[0] } sub finish { shift->sth->finish } sub hashes { _collect($_[0]->_expand(@{$_[0]->sth->fetchall_arrayref({})})) } sub new { my $self = shift->SUPER::new(@_); ($self->{sth}{private_mojo_results} //= 0)++; return $self; } sub rows { shift->sth->rows } sub text { tablify shift->arrays } sub _collect { Mojo::Collection->new(@_) } sub _expand { my ($self, @rows) = @_; return @rows unless $self->{expand} && $rows[0]; my ($idx, $name) = @$self{qw(idx name)}; unless ($idx) { my $types = $self->sth->{pg_type}; my @idx = grep { $types->[$_] eq 'json' || $types->[$_] eq 'jsonb' } 0 .. $#$types; ($idx, $name) = @$self{qw(idx name)} = (\@idx, [@{$self->columns}[@idx]]); } return @rows unless @$idx; if (ref $rows[0] eq 'HASH') { for my $r (@rows) { $r->{$_} && ($r->{$_} = from_json $r->{$_}) for @$name } } else { for my $r (@rows) { $r->[$_] && ($r->[$_] = from_json $r->[$_]) for @$idx } } return @rows; } 1; =encoding utf8 =head1 NAME Mojo::Pg::Results - Results =head1 SYNOPSIS use Mojo::Pg::Results; my $results = Mojo::Pg::Results->new(sth => $sth); $results->hashes->map(sub { $_->{foo} })->shuffle->join("\n")->say; =head1 DESCRIPTION L is a container for L statement handles used by L. =head1 ATTRIBUTES L implements the following attributes. =head2 db my $db = $results->db; $results = $results->db(Mojo::Pg::Database->new); L object these results belong to. =head2 sth my $sth = $results->sth; $results = $results->sth($sth); L statement handle results are fetched from. =head1 METHODS L inherits all methods from L and implements the following new ones. =head2 array my $array = $results->array; Fetch one row from L and return it as an array reference. =head2 arrays my $collection = $results->arrays; Fetch all rows from L and return them as a L object containing array references. # Process all rows at once say $results->arrays->reduce(sub { $a + $b->[3] }, 0); =head2 columns my $columns = $results->columns; Return column names as an array reference. # Names of all columns say for @{$results->columns}; =head2 expand $results = $results->expand; Decode C and C fields automatically to Perl values for all rows. # Expand JSON $results->expand->hashes->map(sub { $_->{foo}{bar} })->join("\n")->say; =head2 finish $results->finish; Indicate that you are finished with L and will not be fetching all the remaining rows. =head2 hash my $hash = $results->hash; Fetch one row from L and return it as a hash reference. =head2 hashes my $collection = $results->hashes; Fetch all rows from L and return them as a L object containing hash references. # Process all rows at once say $results->hashes->reduce(sub { $a + $b->{money} }, 0); =head2 new my $results = Mojo::Pg::Results->new; my $results = Mojo::Pg::Results->new(sth => $sth); my $results = Mojo::Pg::Results->new({sth => $sth}); Construct a new L object. =head2 rows my $num = $results->rows; Number of rows. =head2 text my $text = $results->text; Fetch all rows from L and turn them into a table with L. =head1 SEE ALSO L, L, L. =cut