$attrs->{where}, $attrs
);
- return (@data ? ($self->_construct_object(@data))[0] : ());
+ return (@data ? ($self->_construct_object(@data))[0] : undef);
}
# _is_unique_query
? @{delete $self->{stashed_row}}
: $self->cursor->next
);
- return unless (@row);
+ return undef unless (@row);
my ($row, @more) = $self->_construct_object(@row);
$self->{stashed_objects} = \@more if @more;
return $row;
submitting to a $resultset->create(...) method.
In void context, C<insert_bulk> in L<DBIx::Class::Storage::DBI> is used
-to insert the data, as this is a fast method.
+to insert the data, as this is a faster method.
Otherwise, each set of data is inserted into the database using
L<DBIx::Class::ResultSet/create>, and a arrayref of the resulting row
objects is returned.
-i.e.,
+Example: Assuming an Artist Class that has many CDs Classes relating:
- $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 }
- ]
- },
- { name => 'Like I Give a Damn' }
-
- ] );
+ 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
-use Data::Dump qw/dump/;
sub populate {
- my ($self, $data) = @_; #warn dump $self->result_source->primary_columns;
+ my ($self, $data) = @_;
if(defined wantarray) {
my @created;
push(@created, $self->create($item));
}
return @created;
- }
- else
- {
+ } else {
my ($first, @rest) = @$data;
-
- ## We assume for now that the first item is required to name all the columns
- ## and relationships similarly to how schema->populate requires a first item
- ## of all the column names.
-
- my @names = grep { !$self->result_source->has_relationship($_) } keys %$first;
-
+
+ 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,
- [map { [ map {defined $_ ? $_ : $self->throw_exception("Undefined value for column!")} @$_{@names} ] } @$data]
- );
-
- ## Again we assume the first row has to define all the related resultsets
- my @rels = grep { $self->result_source->has_relationship($_) } keys %$first;
- my @pks = $self->result_source->primary_columns;
-
- ## Must have PKs to use this!!!
-
- foreach my $item (@$data)
- {
- ## First we need to get a result for each
- ## We need to call populate for each relationship.
+ $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;
- foreach my $rel (@rels)
- {
- my $result = $self->find(map {{$_=>$item->{$_}} } @pks);
-
- my @discard = $result->$rel->populate($item->{$rel});
- #$result->$rel->populate($item->{$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 );
+ }
+ }
}
}
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);
my $join_count = $seen->{$rel};
my $alias = ($join_count > 1 ? join('_', $rel, $join_count) : $rel);
- $self->_source_handle->schema->resultset($rel_obj->{class})->search_rs(
- undef, {
- %{$self->{attrs}||{}},
- join => undef,
- prefetch => undef,
- select => undef,
- as => undef,
- alias => $alias,
- where => $self->{cond},
- seen_join => $seen,
- from => $from,
- });
+ #XXX - temp fix for result_class bug. There likely is a more elegant fix -groditi
+ my %attrs = %{$self->{attrs}||{}};
+ delete $attrs{result_class};
+
+ my $new_cache;
+
+ if (my $cache = $self->get_cache) {
+ if ($cache->[0] && $cache->[0]->related_resultset($rel)->get_cache) {
+ $new_cache = [ map { @{$_->related_resultset($rel)->get_cache} }
+ @$cache ];
+ }
+ }
+
+ my $new = $self->_source_handle
+ ->schema
+ ->resultset($rel_obj->{class})
+ ->search_rs(
+ undef, {
+ %attrs,
+ join => undef,
+ prefetch => undef,
+ select => undef,
+ as => undef,
+ alias => $alias,
+ where => $self->{cond},
+ seen_join => $seen,
+ from => $from,
+ });
+ $new->set_cache($new_cache) if $new_cache;
+ $new;
};
}