[Dbix-class] counter handling

Jim Spath jspath at pangeamedia.com
Mon Feb 26 21:42:12 GMT 2007


I don't believe find_or_create can be safely used to increment a 
counter, although I could be wrong.

 From Resultset.pm:

   my $exists   = $self->find($hash, $attrs);
   return defined $exists ? $exists : $self->create($hash);

A row could be inserted after the code checks for the row and before it 
inserts the new row, which would result in an error.

Jason Kohles wrote:
> On Feb 26, 2007, at 3:46 PM, Jim Spath wrote:
>> I am somewhat new to DBIx::Class and was wondering if the following 
>> method is the best way to handle counter values.  I've tested it, and 
>> it works, but wasn't sure if there was a better way.
>>
>> ==================================================
>> (all model, table, and column names are made up)
>> (I'm using DBIx::Class under Catalyst, hence the $c)
>> ==================================================
>>
> 
> Seems like you could save yourself a lot of unnecessary logic...
> 
> $c->model( 'SomeDB::Counter' )->find_or_create({
>     counter_name => $counter_name
> })->update({
>     counter => \'counter+1';
> });
> 
>> my $rows = $c->model('SomeDB::Counter')->search({
>>   counter_name => $counter_name,
>> })->update({
>>   counter => \'counter + 1',
>> });
>>
>> if ($rows eq '0E0') {
>>
>>   eval {
>>     $c->model('SomeDB::Counter')->create({
>>       counter_name => $counter_name,
>>       counter      => 1,
>>     });
>>   };
>>
>>   if ($@) {
>>     if ($@ =~ /duplicate entry/i) {
>>
>>       $rows = $c->model('SomeDB::Counter')->search({
>>         counter_name => $counter_name,
>>       })->update({
>>         counter => \'counter + 1',
>>       });
>>
>>       if ($rows eq '0E0') {
>>         # couldn't update or insert counter
>>       }
>>
>>     } else {
>>       # unknown error on attempted insert
>>     }
>>   }
>> }



More information about the Dbix-class mailing list