2014-08-28 38 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 }); 
}