[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