Class::DBI::Sweetで集約関数を使う方法

Class::DBI::Sweetで集約関数を使う方法

 そのうち本家で対応するんじゃないかって気もしますが。

 とりあえずSUM()だけ。

package MyData::CD;
use Class::DBI::Sweet 0.08; # 0.05では動きません。0.06以降なら大丈夫かも(未確認)。
__PACKAGE__->set_sql( Join_Retrieve_Sum => <<__SQL__ );
  SELECT SUM( %s )
  FROM   %s
  WHERE  %s
__SQL__
sub sum {
  my $proto = shift;
  my $class = ref($proto) || $proto;
  my $sum_column = shift;

  my ( $criteria, $attributes ) = $class->_search_args(@_);

  # make sure we take copy of $attribues since it can be reused
  my $sum_attr = { %{$attributes} };

  # no need for LIMIT/OFFSET and ORDER BY in SUM()
  delete @{$sum_attr}{qw( rows offset order_by )};

  my ( $sql_parts, $classes, $columns, $values )
        = $proto->_search( $criteria, $sum_attr );

  my $sql_method = 'sql_' . ($attributes->{sql_method} || 'Join_Retrieve');
  $sql_method .= '_Sum';

  my $sth = $class->$sql_method( "me.$sum_column", @{%$sql_parts}{qw/ from where /} );

  $class->_bind_param( $sth, $columns );

  return $sth->select_val(@$values);
}

package main;
# artistがfooであるCDのpriceを合計する
my $sum = MyData::CD->sum( price => artist => 'foo' );

 COUNT(*)してるClass::DBI::Sweet::countをパクっただけです。プラグインでも作って自動生成するといいかなー、と思いつつ*1Class::DBI::Sweet::Toppingに既にあったりするとヤだなぁ。

 これでJOINしまくりの集約関数も一発で計算してくれる、はず。

*1:importするのは書いた。