[Dbix-class] Bug in DBIx::Class v0.06999_03

Matt S Trout dbix-class at trout.me.uk
Tue Jun 27 22:28:50 CEST 2006


Jonas wrote:
> Hi,
> 
> I think the new dbic dev version has a bug.
> With dbic 0.06003 this peace of code
> 
> $model->schema->txn_do( sub {
>             for my $attrs ( map $self->_relationship_attrs($table,
> $_), $table->relationships ) {
>                 if ($attrs->{type} eq 'many_to_many') {
>                     $item->delete_related($attrs->{rel_name}, {
> $attrs->{foreign_col} => $item->id });
>                     for my $id ($c->req->param( $attrs->{rel_name} )) {
>                         next unless $id;
>                         $item->create_related($attrs->{rel_name}, {
>                             $attrs->{foreign_col}    => $item->id,
>                             $attrs->{other_self_col} => $id,
>                         });
>                     }
>                 } elsif ($attrs->{type} eq 'has_many') {
>                     $item->search_related($attrs->{rel_name}, {
>                         $attrs->{foreign_col} => $item->id,
>                         $attrs->{self_col} => { -not_in => [
> $c->req->param( $attrs->{rel_name} ) ] },
>                     })->delete;
>                     $item->search_related($attrs->{rel_name}, {
>                         $attrs->{self_col} => [ grep $_,
> $c->req->param( $attrs->{rel_name} ) ]
>                     })->update({ $attrs->{foreign_col} => $item->id });
>                 }
>             }
>             $item->update;
> });
> 
> returns the next sql statments:
> 
> BEGIN WORK
> DELETE FROM dvd WHERE ( ( ( id NOT IN ( ? ) AND owner = ? ) ) ) (`5', `1')
> UPDATE dvd SET owner = ? WHERE ( ( ( ( ( id = ? ) ) ) ) ) (`1', `5')
> DELETE FROM user_role WHERE ( ( ( user = ? ) ) ) (`1')
> INSERT INTO user_role (role, user) VALUES (?, ?) (`2', `1')
> DELETE FROM dvd WHERE ( ( ( current_owner = ? AND id NOT IN ( ? ) ) )
> ) (`1', `5')
> UPDATE dvd SET current_owner = ? WHERE ( ( ( ( ( id = ? ) ) ) ) ) (`1', `5')
> COMMIT
> 
> But with dbic v0.06999_03 the returned statements are:
> 
> DELETE FROM dvd WHERE ( ( ( id NOT IN ( ? ) AND owner = ? ) AND (
> owner = ? ) ) ): '5', '1', '1'
> UPDATE dvd SET owner = ? WHERE ( ( ( ( ( id = ? ) ) ) AND ( owner = ?
> ) ) ): '1', '5', '1'
> DELETE FROM user_role WHERE ( ( ( user = ? ) AND ( user = ? ) ) ): '1', '1'
> INSERT INTO user_role (role, user) VALUES (?, ?): '2', '1'
> DELETE FROM dvd WHERE ( ( ( current_owner = ? AND id NOT IN ( ? ) )
> AND ( current_owner = ? ) ) ): '1', '5', '1'
> UPDATE dvd SET current_owner = ? WHERE ( ( ( ( ( id = ? ) ) ) AND (
> current_owner = ? ) ) ): '1', '5', '1'
> 
> Note the repetition of fields in the where clause and the absence of
> "BEGIN WORK" and "COMMIT" staments.
> 
> The dvd table has 2 fields that are FK's of the user table. Maybe that
> is confusing dbic.

Aha, got it.

the absence of BEGIN WORK / COMMIT is due to a change in the logging; that'll 
be fixed in -current shortly.

The condition duplication is because you shouldn't have needed to supply the 
conditions at all, delete_related should have done it for you. Unfortunately 
there was a bug where it didn't, which is fixed in 06999.

-- 
      Matt S Trout       Offering custom development, consultancy and support
   Technical Director    contracts for Catalyst, DBIx::Class and BAST. Contact
Shadowcat Systems Ltd.  mst (at) shadowcatsystems.co.uk for more information

+ Help us build a better perl ORM: http://dbix-class.shadowcatsystems.co.uk/ +



More information about the Dbix-class mailing list