From: Matt S Trout Date: Sat, 19 May 2007 20:05:13 +0000 (+0000) Subject: Merge 'DBIx-Class-current' into 'bulk_create' X-Git-Tag: v0.08010~150^2~51^2 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=a603987e54ed3022c6d3144f61d294cf96012f22;hp=-c;p=dbsrgits%2FDBIx-Class.git Merge 'DBIx-Class-current' into 'bulk_create' r51635@cain (orig r3331): matthewt | 2007-05-19 15:05:13 +0000 result_source must be passed to new_result --- a603987e54ed3022c6d3144f61d294cf96012f22 diff --combined lib/DBIx/Class/ResultSet.pm index e77108b,58a411a..df5b998 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@@ -350,13 -350,11 +350,13 @@@ sub find my (%related, $info); - foreach my $key (keys %$input_query) { + KEY: foreach my $key (keys %$input_query) { if (ref($input_query->{$key}) && ($info = $self->result_source->relationship_info($key))) { + my $val = delete $input_query->{$key}; + next KEY if (ref($val) eq 'ARRAY'); # has_many for multi_create my $rel_q = $self->result_source->resolve_condition( - $info->{cond}, delete $input_query->{$key}, $key + $info->{cond}, $val, $key ); die "Can't handle OR join condition in find" if ref($rel_q) eq 'ARRAY'; @related{keys %$rel_q} = values %$rel_q; @@@ -1240,110 -1238,6 +1240,110 @@@ sub delete_all return 1; } +=head2 populate + +=over 4 + +=item Arguments: $source_name, \@data; + +=back + +Pass an arrayref of hashrefs. Each hashref should be a structure suitable for +submitting to a $resultset->create(...) method. + +In void context, C in L is used +to insert the data, as this is a faster method. + +Otherwise, each set of data is inserted into the database using +L, and a arrayref of the resulting row +objects is returned. + +Example: Assuming an Artist Class that has many CDs Classes relating: + + my $Artist_rs = $schema->resultset("Artist"); + + ## Void Context Example + $Artist_rs->populate([ + { artistid => 4, name => 'Manufactured Crap', cds => [ + { title => 'My First CD', year => 2006 }, + { title => 'Yet More Tweeny-Pop crap', year => 2007 }, + ], + }, + { artistid => 5, name => 'Angsty-Whiny Girl', cds => [ + { title => 'My parents sold me to a record company' ,year => 2005 }, + { title => 'Why Am I So Ugly?', year => 2006 }, + { title => 'I Got Surgery and am now Popular', year => 2007 } + ], + }, + ]); + + ## Array Context Example + my ($ArtistOne, $ArtistTwo, $ArtistThree) = $Artist_rs->populate([ + { name => "Artist One"}, + { name => "Artist Two"}, + { name => "Artist Three", cds=> [ + { title => "First CD", year => 2007}, + { title => "Second CD", year => 2008}, + ]} + ]); + + print $ArtistOne->name; ## response is 'Artist One' + print $ArtistThree->cds->count ## reponse is '2' + +=cut + +sub populate { + my ($self, $data) = @_; + + if(defined wantarray) { + my @created; + foreach my $item (@$data) { + push(@created, $self->create($item)); + } + return @created; + } else { + my ($first, @rest) = @$data; + + my @names = grep { !ref $first->{$_} } keys %$first; + + my @values = map { + [ map { + defined $_ ? $_ : $self->throw_exception("Undefined value for column!") + } @$_{@names} ] + } @$data; + + $self->result_source->storage->insert_bulk( + $self->result_source, + \@names, + \@values, + ); + + my @rels = grep { $self->result_source->has_relationship($_) } keys %$first; + my @pks = $self->result_source->primary_columns; + + foreach my $item (@$data) { + + foreach my $rel (@rels) { + next unless $item->{$rel}; + + my $parent = $self->find(map {{$_=>$item->{$_}} } @pks) || next; + my $child = $parent->$rel; + + my $related = $child->result_source->resolve_condition( + $parent->result_source->relationship_info($rel)->{cond}, + $child, + $parent, + ); + + my @rows_to_add = ref $item->{$rel} eq 'ARRAY' ? @{$item->{$rel}} : ($item->{$rel}); + my @populate = map { {%$_, %$related} } @rows_to_add; + + $child->populate( \@populate ); + } + } + } +} + =head2 pager =over 4 @@@ -1417,7 -1311,8 +1417,8 @@@ sub new_result my %new = ( %{ $self->_remove_alias($values, $alias) }, %{ $self->_remove_alias($collapsed_cond, $alias) }, - -source_handle => $self->_source_handle + -source_handle => $self->_source_handle, + -result_source => $self->result_source, # DO NOT REMOVE THIS, REQUIRED ); return $self->result_class->new(\%new);