2007年3月12日

SQL::Abstract を勝手に拡張

DBIx::Simple を使っていて、SQL::Abstract が、"GROUP BY" 句 に対応していないので、勝手にプラグインっぽいの作って、対応させたのだが、、、いいのだろうか、、、;
"SQL/Abstract/Plugin/Groupby.pm" っての勝手に作って、以下のようなコードを書いたのだけど、、ほとんど、SQL::Abstract の "order by" の実装をパクッただけ、、、orz
ちなみに、な部分以外はオリジナルを持ってきた、、、。
package SQL::Abstract::Plugin::Groupby;
use Carp;
use strict;

our $VERSION = '0.01';

sub puke (@);

sub where {
my $self = shift;
my $where = shift;
my $order = shift;

# Need a separate routine to properly wrap w/ "where"
my $sql = '';
my @ret = $self->_recurse_where($where);
if (@ret) {
my $wh = shift @ret;
$sql .= $self->_sqlcase(' where ') . $wh if $wh;
}

# group by?
if (ref $order eq 'HASH') {
$sql .= $self->_group_by($order->{group_by}) if $order->{group_by};
$sql .= $self->_order_by($order->{order_by}) if $order->{order_by};
# order by?
} elsif ($order) {
$sql .= $self->_order_by($order);
}

return wantarray ? ($sql, @ret) : $sql;
};

sub _group_by {
my $self = shift;
my $ref = ref $_[0];
puke "Undefined group_by data struct" unless $_[0];

my @vals = $ref eq 'ARRAY' ? @{$_[0]} :
$ref eq 'SCALAR' ? ${$_[0]} :
$ref eq '' ? $_[0] :
puke "Unsupported data struct $ref for GROUP BY";

my $val = join ', ', map { $self->_quote($_) } @vals;
return $val ? $self->_sqlcase(' group by')." $val" : '';
};

{
no strict 'refs';
*SQL::Abstract::where = \&where;
*SQL::Abstract::_group_by = \&_group_by;
}
ってか、"group by" って、一般的な RDBMS で対応しているのかどうか、不安なので俺々勝手モジュールだけにしておく、、。コメントとか頂けたら嬉しいかもです。。。とか、勝手に言ってみる、、、orz

ちなみに使い方は、こんな感じです。。気分的には、DBIx::Class インスパイア?!っでも無いか、、orz
use SQL::Abstract;
use SQL::Abstract::Plugin::Groupby;

my ($query, @bind) = SQL::Abstract->new->select(
'table_name',
[qw/field1 field2/],
{field1 => 'value1'},
{
group_by => [qw/field1/],
order_by => [qw/field2/],
},
);

0 件のコメント: