X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FStorage%2FDBI.pm;h=405041c8836a6e9026fa85bbd495413749ee3a17;hb=30ae562b00055d0d5943022b1ffd6cc78736ea43;hp=0efe3d19cd2badca249b66f7b711e3f42d668a34;hpb=40c628f3c406c6edffb3f5ac0cdc4245119b7c25;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Storage/DBI.pm b/lib/DBIx/Class/Storage/DBI.pm index 0efe3d1..405041c 100644 --- a/lib/DBIx/Class/Storage/DBI.pm +++ b/lib/DBIx/Class/Storage/DBI.pm @@ -1581,6 +1581,14 @@ sub _subq_update_delete { # quick check if we got a sane rs on our hands my @pcols = $rsrc->primary_columns; + unless (@pcols) { + $self->throw_exception ( + sprintf ( + "You must declare primary key(s) on source '%s' (via set_primary_key) in order to update or delete complex resultsets", + $rsrc->source_name || $rsrc->from + ) + ); + } my $sel = $rs->_resolved_attrs->{select}; $sel = [ $sel ] unless ref $sel eq 'ARRAY'; @@ -1765,12 +1773,52 @@ sub _select_args { if ( ( $attrs->{rows} && keys %{$attrs->{collapse}} ) || - ( $attrs->{group_by} && @{$attrs->{group_by}} && - $attrs->{_prefetch_select} && @{$attrs->{_prefetch_select}} ) + ( $attrs->{group_by} + && + @{$attrs->{group_by}} + && + $attrs->{_prefetch_select} + && + @{$attrs->{_prefetch_select}} + ) ) { + ($ident, $select, $where, $attrs) = $self->_adjust_select_args_for_complex_prefetch ($ident, $select, $where, $attrs); } + + elsif ( + ($attrs->{rows} || $attrs->{offset}) + && + $sql_maker->limit_dialect eq 'RowNumberOver' + && + (ref $ident eq 'ARRAY' && @$ident > 1) # indicates a join + && + scalar $sql_maker->_order_by_chunks ($attrs->{order_by}) + ) { + # the RNO limit dialect above mangles the SQL such that the join gets lost + # wrap a subquery here + + push @limit, delete @{$attrs}{qw/rows offset/}; + + my $subq = $self->_select_args_to_query ( + $ident, + $select, + $where, + $attrs, + ); + + $ident = { + -alias => $attrs->{alias}, + -source_handle => $ident->[0]{-source_handle}, + $attrs->{alias} => $subq, + }; + + # all part of the subquery now + delete @{$attrs}{qw/order_by group_by having/}; + $where = undef; + } + elsif (! $attrs->{software_limit} ) { push @limit, $attrs->{rows}, $attrs->{offset}; } @@ -1992,7 +2040,7 @@ sub last_insert_id { This API is B, will almost definitely change in the future, and currently only used by L<::AutoCast|DBIx::Class::Storage::DBI::AutoCast> and -L<::Sybase|DBIx::Class::Storage::DBI::Sybase>. +L<::Sybase::ASE|DBIx::Class::Storage::DBI::Sybase::ASE>. The default implementation returns C, implement in your Storage driver if you need this functionality. @@ -2325,10 +2373,19 @@ sub deployment_statements { data => $schema, ); - my $ret = $tr->translate - or $self->throw_exception( 'Unable to produce deployment statements: ' . $tr->error); + my @ret; + my $wa = wantarray; + if ($wa) { + @ret = $tr->translate; + } + else { + $ret[0] = $tr->translate; + } + + $self->throw_exception( 'Unable to produce deployment statements: ' . $tr->error) + unless (@ret && defined $ret[0]); - return $ret; + return $wa ? @ret : $ret[0]; } sub deploy {