だるろぐ

だるいぶろぐです

Data::ObjectDriverでDBMSの関数を使った上で複数のカラムをselectするなど

Data::ObjectDriver(以下DOD)でgroup byとかsumとかcountとかのmysqlの関数を使う場合は、Data::ObjectDriver::SQLインスタンスを作ってそいつに色々オプションを指定した上でdriverを呼んでselect_oneしてやる。

my $st = Data::ObjectDriver::SQL->new;
$st->from(["guest2site"]);
$st->add_where(guest_id => 2);
$st->add_select("sum(site_id)" => "sitesum");
$st->group({column => "guest_id"});

my $r = Guest2Site->driver->select_one($st->as_sql, $st->{bind});
p [$st->as_sql, $st->{bind}, $r];
[
  'SELECT sum(site_id) sitesum
FROM guest2site
WHERE (guest_id = ?)
GROUP BY guest_id
',
  [
    2
  ],
  '55'
]


このselect_oneの返り値はただの数値であってオブジェクトではない。(まあこの場合はsumだから当然そうなのだけど)
で、だ。
select_oneはその名のとおり、一つのカラムしかselectできない。例えばsumではなくgroup byとかする場合は、一つではなく複数のカラムをselectしたいときがほとんどだと思う。
そんなときはdbhまで呼んでDBIのメソッドを呼ぶ。

$st = Data::ObjectDriver::SQL->new;
$st->from(['guest2site']);
$st->group({column => 'guest_id'});

$st->add_select('guest_id');
$st->add_select('SUM(site_id)' => "sid");

$st->add_where(id => {op => "<", value => 36});

my $dbh = Guest2Site->driver->r_handle;
my $sth = $dbh->prepare($st->as_sql);
$sth->execute(@{ $st->{bind} });
my $v = $sth->fetchall_arrayref;
p [$st->as_sql, $st->{bind}, $v];
[
  'SELECT guest_id, SUM(site_id) sid
FROM guest2site
WHERE (id < ?)
GROUP BY guest_id
',
  [
    36
  ],
  [
    [
      '1',
      '55'
    ],
    [
      '2',
      '55'
    ],
    [
      '3',
      '55'
    ],
    [
      '4',
      '15'
    ]
  ]
]

というかむしろpodにはこういう使い方しか載っておらず、select_oneについての説明は無い。コード嫁の精神ですね、分かります。

何が言いたかったかというと

DBIのメソッド使うんじゃなくて、DODにselect_multiみたいな名前の複数のカラムをselect出来るメソッドあればいいのになーと思いましたという話。
6Aではこういうクエリを吐きたい場合はどうしてるんだろう。


今回使ったソース。
GitHub - hirafoo/sample_dod