package Local::DBIx::Lite::ResultSet; # provides hash, hashes, array, arrays, map, map_hashes, list, flat + new row, # column & value methods to DBIx::Lite::ResultSet # used by Local::DBIxLite use parent 'DBIx::Lite::ResultSet'; use Data::Printer alias => 'ddp'; use Data::Dumper; use 5.26.0; # ============= new DBIx::Simple::Result methods =============================== sub column { shift->flat(@_) } sub value { $_[0]->array->[-1] } # ie my $ref = $_[0]->array; return $ref->[-1] sub row { shift->list(@_) } # ============================================================================== # returns single hash or hashref: sub hash { my $ref = $_[0]->single->hashref; # ddp $ref; return wantarray ? %$ref : $ref; } # returns array(ref): sub array { my $self = shift; # DBIx::Lite::ResultSet object my $cols = $self->column_names; # _debug($cols); my $data = $self->single->hashref; # _debug($ref); my @vals = @{$data}{@$cols}; # _debug(@vals); return wantarray ? @vals : \@vals; # DBIx::Simple only returns arrayref } # returns array (or ref to array) of arrayrefs: sub arrays { my $self = shift; # DBIx::Lite::ResultSet object my $cols = $self->column_names; # _debug($cols); my @all = $self->all; # array of DBIx::Lite::Row objects my @data = map { [ @{ $_->hashref }{ @$cols } ]; } @all; return wantarray ? @data : \@data; } # returns array (or ref to array) of hashrefs: sub hashes { my @all = $_[0]->all; # array of DBIx::Lite::Row objects my @data = map $_->hashref, @all; # _debug(@data); return wantarray ? @data : \@data; } # returns single table col as array or arrayref sub flat { my $self = shift; # _debug($rs); # DBIx::Lite::ResultSet object my $col = $self->{select}->[0]; # _debug($col); my @all = $self->all; # array of DBIx::Lite::Row objects my @data = map $_->get($col), @all; return wantarray ? @data : \@data; } # intended as single row query, return list in array context or last value for scalar: sub list { my @data = $_[0]->array; # _debug(@data); return wantarray ? @data : $data[-1]; } # returns hash(ref) map of 2 cols: sub map { my $self = shift; # DBIx::Lite::ResultSet object my $cols = $self->{select}; my @all = $self->all; # array of DBIx::Lite::Row objects my %map = map { @{ $_->hashref }{ @$cols }; } @all; # _debug(%map); return wantarray ? %map : \%map; } # adapted from DBIx::Simple::map_hashes: sub map_hashes { my ($self, $keyname) = @_; # ddp $keyname; Carp::croak('Key column name not optional') unless defined $keyname; my @rows = $self->hashes; # _debug(@rows); # array of hashrefs Carp::croak(qq!Key column name "$keyname" not found!) unless grep { defined $_->{$keyname} } @rows; # defined in case zeros # create array of $keyname vals & delete corresponding key/val from each href: my @keys = map { delete $_->{$keyname} } @rows; # ddp @keys; my %data; # hash of @rows hrefs, indexed by @keys: @data{@keys} = @rows; # _debug(%data); return wantarray ? %data : \%data; } # adapted from DBIx::Simple::map_arrays: sub map_arrays { my ($self, $keyindex) = @_; # p $keyindex; # position in array to create hash key Carp::croak('Key index value not optional') unless defined $keyindex; # $keyindex += 0; # will croak if not number, and necessary if $keyindex defined? my @rows = $self->arrays; # ddp @rows; Carp::croak(qq!Key index value "$keyindex" not found!) unless grep { defined $_->[$keyindex] } @rows; # defined in case zeros my @keys = map { splice @$_, $keyindex, 1 } @rows; my %data; @data{@keys} = @rows; return wantarray ? %data : \%data; } # modifies @_ directly; must supply separate $var(s), not @list # eg ->into( my($a,$b) ): sub into { # warn Dumper @_; my ($self, @vars) = @_; my @data = $self->array; # _debug(@data); { # match DBIx::Simple bind_cols error message: my $x = scalar @vars; my $y = scalar @data; die 'into() method called with '.$x.' values but '.$y.' are needed' if $x != $y; } # return \@data; # how DBIx::Simple returns - doesn't work here my $i = 1; # array index counter, starts at 1 to preserve $_[0] $_[$i++] = $_ for @data; } sub _debug { ddp @_ } 1;