From: Peter Rabbitson Date: Thu, 22 May 2014 11:37:08 +0000 (+0200) Subject: Fix multi-value literal populate not working with simplified bind spec X-Git-Tag: v0.082800~217 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=90b2bd88b27275885ebaad6de8545ad264bf9cb6;p=dbsrgits%2FDBIx-Class.git Fix multi-value literal populate not working with simplified bind spec This arcane use-case got missed when 1b5ddf23 was integrated --- diff --git a/Changes b/Changes index 387cb0a..784b3d1 100644 --- a/Changes +++ b/Changes @@ -4,6 +4,8 @@ Revision history for DBIx::Class - Fix on_connect_* not always firing in some cases - a race condition existed between storage accessor setters and the determine_driver routines, triggering a connection before the set-cycle is finished + - Fix multi-value literal populate not working with simplified bind + specifications 0.08270 2014-01-30 21:54 (PST) * Fixes diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 1a302ce..75c8434 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -1695,13 +1695,10 @@ sub _gen_sql_bind { sub _resolve_bindattrs { my ($self, $ident, $bind, $colinfos) = @_; - $colinfos ||= {}; - my $resolve_bindinfo = sub { #my $infohash = shift; - %$colinfos = %{ $self->_resolve_column_info($ident) } - unless keys %$colinfos; + $colinfos ||= { %{ $self->_resolve_column_info($ident) } }; my $ret; if (my $col = $_[0]->{dbic_colname}) { @@ -1721,10 +1718,16 @@ sub _resolve_bindattrs { my $resolved = ( ref $_ ne 'ARRAY' or @$_ != 2 ) ? [ {}, $_ ] : ( ! defined $_->[0] ) ? [ {}, $_->[1] ] - : (ref $_->[0] eq 'HASH') ? [ (exists $_->[0]{dbd_attrs} or $_->[0]{sqlt_datatype}) - ? $_->[0] - : $resolve_bindinfo->($_->[0]) - , $_->[1] ] + : (ref $_->[0] eq 'HASH') ? [( + ! keys %{$_->[0]} + or + exists $_->[0]{dbd_attrs} + or + $_->[0]{sqlt_datatype} + ) ? $_->[0] + : $resolve_bindinfo->($_->[0]) + , $_->[1] + ] : (ref $_->[0] eq 'SCALAR') ? [ { sqlt_datatype => ${$_->[0]} }, $_->[1] ] : [ $resolve_bindinfo->( { dbic_colname => $_->[0] } @@ -2291,12 +2294,21 @@ sub _dbh_execute_for_fetch { my $fetch_tuple = sub { return undef if ++$fetch_row_idx > $#$data; - return [ map { defined $_->{_literal_bind_subindex} - ? ${ $data->[ $fetch_row_idx ]->[ $_->{_bind_data_slice_idx} ]} - ->[ $_->{_literal_bind_subindex} ] - ->[1] - : $data->[ $fetch_row_idx ]->[ $_->{_bind_data_slice_idx} ] - } map { $_->[0] } @$proto_bind]; + return [ map { + ! defined $_->{_literal_bind_subindex} + + ? $data->[ $fetch_row_idx ]->[ $_->{_bind_data_slice_idx} ] + + # There are no attributes to resolve here - we already did everything + # when we constructed proto_bind. However we still want to sanity-check + # what the user supplied, so pass stuff through to the resolver *anyway* + : $self->_resolve_bindattrs ( + undef, # a fake rsrc + [ ${ $data->[ $fetch_row_idx ]->[ $_->{_bind_data_slice_idx} ]}->[ $_->{_literal_bind_subindex} ] ], + {}, # a fake column_info bag + )->[0][1] + + } map { $_->[0] } @$proto_bind ]; }; my $tuple_status = []; diff --git a/t/100populate.t b/t/100populate.t index 177231a..4a3f0ac 100644 --- a/t/100populate.t +++ b/t/100populate.t @@ -196,7 +196,7 @@ is($link7->title, 'gtitle', 'Link 7 title'); # test mixed binds with literal sql/bind $rs->populate([ map { +{ - url => \[ '? || ?', [ {} => 'cpan.org_' ], [ undef, $_ ] ], + url => \[ '? || ?', [ {} => 'cpan.org_' ], $_ ], title => "The 'best of' cpan", } } (1 .. 5) ]);