[DBIx-Class-Devel] Optimized update_or_create

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


On Mon, Jul 15, 2013 at 11:02:00AM +0200, Alexander Hartmaier wrote:
> On Fri, Jul 12, 2013 at 9:52 PM, fREW Schmidt <frioux at gmail.com> wrote:
> 
> > Currently create_or_update uses exactly two queries; one to load the
> > row, another to update it if it is found or insert it if it is not
> > found.
> >
> > For properly written DBD's (one would hope that is most, but I
> > wouldn't assume it :) this can be rewritten to just be a single
> > update, like this:
> >
> >    sub update_or_create {
> >      my $self = shift;
> >      my $attrs = (@_ > 1 && ref $_[$#_] eq 'HASH' ? pop(@_) : {});
> >      # begin handwaving (we need to correctly find the UC or PK)

This handwaving is exceedingly non-trivial. Read the source of find()

> >      my $cond = ref $_[0] eq 'HASH' ? shift : {@_};
> >
> >      # can't use unless because 0e0 is returned on error
> >      $self->create($cond) if $self->search($search)->update($cond) == 0;
> >
> >      return
> >    }
> >
> > This breaks backcompat in two serious ways: first it uses the
> > resultset update instead of the row update, and second it doesn't
> > return the created/updated row.
> >
> > I'll probably make a helper that will do this, but I was wondering
> > what people though of for names?  Something like
> > update_or_insert since you don't get the object back?  I don't like
> > update_or_create_fast, but it kinda makes sense.
> >
> > Ideas?
> >
> I never needed create_or_update in any production code

Same here, mainly because of its severe limitations: it takes only one 
argument, which is both used to find and to update. I would never trust 
myself to keep this in mind at all times and sanitize the input 
properly.

> We already have code that behaves differently depending on context, maybe
> void context can be used to detect if the users needs the row object, if
> not use the optimized code path?

This is a design mistake worse than the list/scalar behavior of 
resultsets. Please try to not perpetuate it further.

As far as naming etc - I don't have an opinion, sorry.

Cheers




More information about the DBIx-Class-Devel mailing list