From: Luke Saunders Date: Fri, 7 Apr 2006 17:29:21 +0000 (+0000) Subject: new class ResultSetColumn and tests X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=2bb7b40b94dd99970f48179d0dc945852a3a1557;p=dbsrgits%2FDBIx-Class-Historic.git new class ResultSetColumn and tests --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index c012011..191151f 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -10,6 +10,7 @@ use Data::Page; use Storable; use Scalar::Util qw/weaken/; +use DBIx::Class::ResultSetColumn; use base qw/DBIx::Class/; __PACKAGE__->load_components(qw/AccessorGroup/); __PACKAGE__->mk_group_accessors('simple' => qw/result_source result_class/); @@ -414,6 +415,28 @@ sub single { return (@data ? $self->_construct_object(@data) : ()); } +=head2 get_column + +=over 4 + +=item Arguments: $cond? + +=item Return Value: $resultsetcolumn + +=back + + my $max_length = $rs->get_column('length')->max; + +Returns a ResultSetColumn instance for $column based on $self + +=cut + +sub get_column { + my ($self, $column) = @_; + + my $new = DBIx::Class::ResultSetColumn->new($self, $column); + return $new; +} =head2 search_like diff --git a/lib/DBIx/Class/ResultSetColumn.pm b/lib/DBIx/Class/ResultSetColumn.pm new file mode 100644 index 0000000..133e6ff --- /dev/null +++ b/lib/DBIx/Class/ResultSetColumn.pm @@ -0,0 +1,184 @@ +package DBIx::Class::ResultSetColumn; +use strict; +use warnings; +use base 'DBIx::Class'; + +=head1 NAME + + DBIx::Class::ResultSetColumn - helpful methods for messing + with a single column of the resultset + +=head1 SYNOPSIS + + $rs = $schema->resultset('CD')->search({ artist => 'Tool' }); + $rs_column = $rs->get_column('year'); + $max_year = $rs_column->max; #returns latest year + +=head1 DESCRIPTION + +A convenience class used to perform operations on a specific column of a resultset. + +=cut + +=head1 METHODS + +=head2 new + + my $obj = DBIx::Class::ResultSetColumn->new($rs, $column); + +Creates a new resultset column object from the resultset and column passed as params + +=cut + +sub new { + my ($class, $rs, $column) = @_; + $class = ref $class if ref $class; + + my $object_ref = { _column => $column, + _parent_resultset => $rs }; + + my $new = bless $object_ref, $class; + $new->throw_exception("column must be supplied") unless ($column); + return $new; +} + +=head2 next + +=over 4 + +=item Arguments: none + +=item Return Value: $value + +=back + +Returns the next value of the column in the resultset (C is there is none). + +Much like $rs->next but just returning the one value + +=cut + +sub next { + my $self = shift; + + $self->{_resultset} = $self->{_parent_resultset}->search(undef, {select => [$self->{_column}], as => [$self->{_column}]}) unless ($self->{_resultset}); + my ($row) = $self->{_resultset}->cursor->next; + return $row; +} + +=head2 all + +=over 4 + +=item Arguments: none + +=item Return Value: @values + +=back + +Returns all values of the column in the resultset (C is there are none). + +Much like $rs->all but returns values rather than row objects + +=cut + +sub all { + my $self = shift; + return map {$_->[0]} $self->{_parent_resultset}->search(undef, {select => [$self->{_column}], as => [$self->{_column}]})->cursor->all; +} + +=head2 min + +=over 4 + +=item Arguments: none + +=item Return Value: $lowest_value + +=back + +Wrapper for ->func. Returns the lowest value of the column in the resultset (C is there are none). + +=cut + +sub min { + my $self = shift; + return $self->func('MIN'); +} + +=head2 max + +=over 4 + +=item Arguments: none + +=item Return Value: $highest_value + +=back + +Wrapper for ->func. Returns the highest value of the column in the resultset (C is there are none). + +=cut + +sub max { + my $self = shift; + return $self->func('MAX'); +} + +=head2 sum + +=over 4 + +=item Arguments: none + +=item Return Value: $sum_of_values + +=back + +Wrapper for ->func. Returns the sum of all the values in the column of the resultset. Use on varchar-like columns at your own risk. + +=cut + +sub sum { + my $self = shift; + return $self->func('SUM'); +} + +=head2 func + +=over 4 + +=item Arguments: $function + +=item Return Value: $function_return_value + +=back + +Runs a query using the function on the column and returns the value. For example + $rs $schema->resultset("CD")->search({}); + $rs->get_column('title')->func('LENGTH'); + +Produces the following SQL + SELECT LENGTH( title ) from cd me + +=cut + +sub func { + my $self = shift; + my $function = shift; + + my ($row) = $self->{_parent_resultset}->search(undef, {select => {$function => $self->{_column}}, as => [$self->{_column}]})->cursor->next; + return $row; +} + +1; + +=head1 AUTHORS + +Luke Saunders + +=head1 LICENSE + +You may distribute this code under the same terms as Perl itself. + +=cut diff --git a/t/basicrels/27result_set_column.t b/t/basicrels/27result_set_column.t new file mode 100644 index 0000000..d8d85be --- /dev/null +++ b/t/basicrels/27result_set_column.t @@ -0,0 +1,7 @@ +use Test::More; +use lib qw(t/lib); +use DBICTest; +use DBICTest::BasicRels; + +require "t/run/27result_set_column.tl"; +run_tests(DBICTest->schema); diff --git a/t/helperrels/27result_set_column.t b/t/helperrels/27result_set_column.t new file mode 100644 index 0000000..fd2e13e --- /dev/null +++ b/t/helperrels/27result_set_column.t @@ -0,0 +1,7 @@ +use Test::More; +use lib qw(t/lib); +use DBICTest; +use DBICTest::HelperRels; + +require "t/run/27result_set_column.tl"; +run_tests(DBICTest->schema); diff --git a/t/run/27result_set_column.tl b/t/run/27result_set_column.tl new file mode 100644 index 0000000..e62cb62 --- /dev/null +++ b/t/run/27result_set_column.tl @@ -0,0 +1,23 @@ +sub run_tests { +my $schema = shift; + +plan tests => 5; + +my $rs = $cd = $schema->resultset("CD")->search({}); + +my $rs_title = $rs->get_column('title'); +my $rs_year = $rs->get_column('year'); + +is($rs_title->next, 'Spoonful of bees', "next okay"); + +my @all = $rs_title->all; +cmp_ok(scalar @all, '==', 5, "five titles returned"); + +cmp_ok($rs_year->max, '==', 2001, "max okay for year"); +is($rs_title->min, 'Caterwaulin\' Blues', "min okay for title"); + +cmp_ok($rs_year->sum, '==', 9996, "three artists returned"); + +} + +1;