2014-08-28 44 views
4

我试图在DBIx::Class中模仿update_or_new函数中的SQL。DBIx ::类更新充气列功能

UPDATE user SET lastseen = GREATEST(lastseen, ?::timestamp) WHERE userid = ? 

它详细介绍了充气柱一个错误,说这是无法在undef调用is_infinity

$schema->resultset('user')->update_or_new({ 
    userid => 'peter', 
    lastseen => \[ 'GREATEST(lastseen, ?::timestamp)', DateTime->from_epoch(epoch => 1234) ] 
}); 

我想这是因为InflateColumn::DataTime不期望在那里的功能。这个问题有没有干净的解决方法?

+3

转储SQL。设置环境变量'DBIX_TRACE = 1'来查看它发送的内容。 http://search.cpan.org/~ribasushi/DBIx-Class-0.08270/lib/DBIx/Class/Manual/Troubleshooting.pod – 2014-08-28 18:01:32

+0

它死于放气/膨胀 - 尝试执行sql之前。 – 2014-08-29 01:59:29

+0

它是DBIC_TRACE = 1,但无论如何,DateTime-> from_epoch(1234)是不正确的。如果你想使用那个奇怪的纪元,你需要DateTime-> from_epoch(epoch => 1234)。 '$ perl -MDateTime -E'说DateTime-> from_epoch(1234)' 当调用DateTime :: from_epoch参数时奇数个参数[...] \t DateTime :: from_epoch(undef,1234)叫做-e line 1'这就是为什么inflate不起作用,因为你传递的是undef,因为你在DateTime构造函数上失败 – mikew 2014-08-30 06:18:58

回答

0

这是DBIx :: Class(在此处寻址:https://github.com/dbsrgits/dbix-class/pull/44)中的一个错误,并且修复被合并。下一个版本应该没问题。 这就是说,如果你使用DBIx :: <类= 0.08270 ...

您使用update_or_new,但如果该行已经存在的功能才有意义: GREATEST(lastseen, ?::timestamp) lastseen未定义如果该行没有按还没有存在。

我通过source + docs读了一堆,并找不到一种方法来避开InflateColumn的代码,仍然有绑定值。你可以通过标量ref(\'NOW()')传递字面SQL,但不能传递数组ref。

最好的办法是使用the ResultSet's update method instead,,它不处理/放缩任何传入的值。这与DBIx :: Class :: Row中的相应“更新”不同。

my $dtf = $schema->storage->datetime_parser; #https://metacpan.org/pod/DBIx::Class::Storage::DBI#datetime_parser 
my $user_rs = $schema->resultset('User')->search({ userid => 'peter' }); 
my $dt = DateTime->from_epoch(epoch => 1234); 


#select count(*) where userid = 'peter'; 

if($user_rs->count) { 
    $user_rs->update(
    lastseen => \[ 'GREATEST(lastseen, ?)', $dtf->format_datetime($dt) ] 
); 
} else { 
    $user_rs->create({ lastseen => $dt }); 
}