[DBIx-Class-Devel] Optimized update_or_create

Peter Rabbitson rabbit+dbic at rabbit.us
Mon Jul 15 15:40:24 GMT 2013


On Mon, Jul 15, 2013 at 10:06:45AM -0500, fREW Schmidt wrote:
> 
> Ok, so with the above in mind, maybe a slightly different api would
> be sensible.  How does everyone feel about this:
> 
> (name pending, though I'm leaning towards update_or_insert)

Calling it update_or_insert which is radically different from 
udpate_or_create is not such a good idea. I can't seem to come up with a 
name that is sufficiently visually differnt from 'update_or' while 
conveying the action that is about to take place.

Perhaps we can go full-mongo and provide $rs->upsert (with the side effect of
guaranteed atomicity, either via the storage or via dbic-side txn)?

> 
>    $rs->update_or_insert( \%search, \%update, \%insert? )

This is too verbose, especially given that most of the time \%search will be
a {}.

> 
> The insert_hash is optional because if you have a simple enough case
> the update and insert can be the same (though in my experience that is
> often not the case.)

Kinda... but... We are conflating two issues here - one is that the
original u_or_c mixes the find and the update criteria. This is almost
always a mistake. However *seperating* the update and insert parts
also feels like a mistake most of the time. Can you elaborate which cases
you ran across that needed a different update and insert bag?

Also if you do allow for insert/update bags to differ, then you 
automatically disqualify the ->upsert from RDBMS-side optimizations 
(since most of the U_OR_D operators take only one set of VALUES)

> 
> Another more flexible api might just be:
> 
>    $rs->search( \%search )->update_or_insert( \%update, \%insert? )
> 
> I almost want to just make that latter API and then add a helper or
> two to expand to the former and others (maybe a version where you
> specify the key and values of a given UC?)  Heck, in most of my
> resultsets I tend to write a method to search based on the non-pk
> uc's, so for me I'd do something like:
> 
>    $rs->search_by_name($name)->update_or_insert( ... );

Interesting... find() actually provides this functionality, and we 
already deprecated search( many plain values ) a while ago. I wonder 
whether we can make

search( u1, u2, u3, { key => 'three_value_uc' })

to be equivalent to the find() version with the same syntax



More information about the DBIx-Class-Devel mailing list