[Dbix-class] find redux

Zbigniew Lukasiak zzbbyy at gmail.com
Fri Jan 25 16:10:07 GMT 2008


On Jan 25, 2008 2:30 PM, Matt S Trout <dbix-class at trout.me.uk> wrote:
> On Fri, Jan 25, 2008 at 12:24:27PM +0100, Zbigniew Lukasiak wrote:
> > Let me sidestep that a bit
>
> No, I won't let you.
>
> I spent an hour discussing with people how to structure this discussion so
> we can actually work out how to proceed in a framework that's clear, precise
> and reasonably easy to convert across to code.
>
> Please do me the courtesy of respecting the effort that went into this
> and working within the structure provided.

OK, if that will help you I am happy to provide that help.

I am not sure what you meant in the end note - I'll assume here that
it means that when you say 'all columns' you mean the columns in the
query and in the internal resultset condition.  Correct me if I am
wrong.  This question of including the 'implicite rs columns' is the
most important thing in this whole analysis - because it is the least
understood one.  My opinion is that those columns should be included.

And assuming that I differ with you in the analysis of

Case 1 - called with 'key' attr and all columns for that key

If all the key columns are in the query then the behaviour is correct,
but if one of the columns for the key is in the condition instead of
the query then a search by all columns will be issued.
This was documented in my email from Jan. 17th in the thread rs->find
finds by all columns.
Here I repeat the test case:

my $cd = $schema->resultset("CD")->first;
my $old_artistid = $cd->artist->artistid;
$cd->artist->update( { name => 'new name' } );
$schema->storage->debug(1);
my $art = $cd->update_or_create_related( 'artist', { name => 'some
other name' } );
is( $old_artistid, $art->artistid, 'artist updated not recreated' );


__OUTPUT__

SELECT me.artistid, me.name FROM artist me WHERE ( ( ( me.name = ? )
AND ( me.artistid = ? ) ) ): 'some other name', '1'
INSERT INTO artist (artistid, name) VALUES (?, ?): '1', 'some other name'
DBIx::Class::Relationship::Base::update_or_create_related(): DBI
Exception: DBD::SQLite::st execute failed: PRIMARY KEY must be
unique(19) at dbdimp.c line 403 [for Statement "INSERT INTO artist
(artistid, name) VALUES (?, ?)"] at t/61findnot.t line 16

=head1 better behaviour: find()

The Case 1 is the most important one to fix.

In my opinion if the user provides all the needed columns (be it in
the query or in the internal resultset condition) it should always
return the found record if there is one or return undef if there is no
such record.

Cheers,
Zbigniew
http://perlalchemy.blogspot.com/



More information about the DBIx-Class mailing list