sub populate {
my $self = shift;
-
if (defined wantarray) {
# cruft placed in standalone method
my $data = $self->_normalize_populate_to_hashref(@_);
my $data = $self->_normalize_populate_to_arrayref(@_);
return unless @$data;
+ use DDP; p $data;
my $first = shift @$data;
my (@rels, @columns);
my $rsrc = $self->result_source;
my $rels = { map { $_ => $rsrc->relationship_info($_) } $rsrc->relationships };
- for my $index (0..$#$first) {
- my $col = $first->[$index];
- my $val = $data->[0][$index];
- my $ref = ref $val;
- $rels->{$col} && ($ref eq 'ARRAY' or $ref eq 'HASH')
- ? push @rels, $col
- : push @columns, $col
- ;
+
+ if (ref $data->[0] eq 'CODE') {
+ @columns = @$first;
+ }
+ else {
+ for my $index (0..$#$first) {
+ my $col = $first->[$index];
+ my $val = $data->[0][$index];
+ my $ref = ref $val;
+ $rels->{$col} && ($ref eq 'ARRAY' or $ref eq 'HASH')
+ ? push @rels, $col
+ : push @columns, $col
+ ;
+ }
}
my @pks = $rsrc->primary_columns;
## do the belongs_to relationships
foreach my $index (0..$#$data) {
+ next if (ref $data->[$index] eq 'CODE');
# delegate to list context populate()/create() for any dataset without
# primary keys with specified relationships
- if (grep { defined $colmap{$_} && !defined $data->[$index][$colmap{$_}] } @pks) {
+ if (grep { !defined $colmap{$_} } @pks) {
for my $r (@rels) {
- if (grep { ref $data->[$index][$colmap{$_}] eq $_ } qw/HASH ARRAY/) { # a related set must be a HASH or AoH
- my @ret = $self->populate($data);
+ if (grep { ref $data->[$index][$colmap{$r}] eq $_ } qw/HASH ARRAY/) { # a related set must be a HASH or AoH
+ # we pass in @_ here as it is the pre-normalized version of $data.
+ # in list/scalar context it is expecting this form so we save a step
+ # converting it back
+ my @ret = $self->populate(@_);
return;
}
}
## do the has_many relationships
foreach my $item (@$data) {
+ next if (ref $item eq 'CODE');
my $main_row;
$rel,
);
-=begin
- if ( ref $item->[$colmap{$rel}] eq 'ARRAY') {
- for my $subitem (@{ $item->[$colmap{$rel}] }) {
- $subitem->
-
+ my @rows_to_add = do {
+ if (ref $item->[ $colmap{$rel} ] eq 'ARRAY') {
+ @{$item->[$colmap{$rel}]};
}
- }
+ else {
+ ($item->[$colmap{$rel}]);
+ }
+ };
- my @rows_to_add = ref eq 'ARRAY' ? @{$item->[$colmap{$rel}]} : ($item->[$colmap{$rel}]);
+ # only AoH supports multicreate per doc specs
my @populate = map { {%$_, %$related} } @rows_to_add;
-=cut
- $child->populate( $item->[$colmap{$rel}] );
+ $child->populate(\@populate);
}
}
}
}
# populate() arguments went over several incarnations
-# can be any mixture of :
-# 1. AoA
-# 2. AoH
-# 3. AoS(calar) followed buy Arrayrefref (\@cols, $rs->as_query)
-# 4. coderef (tuple generator)
# What we ultimately support is AoH
sub _normalize_populate_to_hashref {
my ($self, $arg) = @_;
my @ret;
my @colnames = @{$arg->[0]};
foreach my $values (@{$arg}[1 .. $#$arg]) {
- if (ref $values eq 'ARRAY') {
- push @ret, { map { $colnames[$_] => $values->[$_] } (0 .. $#colnames) };
- }
- elsif (ref $values eq 'CODE' || (ref $values eq 'REF' && ref $$values eq 'ARRAY')) {
- push @ret, $values;
- }
- else {
- $self->throw_exception('Populate expects an arrayref of either hashrefs, arrayrefs, coderefs or arrayrefrefs');
- }
+ push @ret, { map { $colnames[$_] => $values->[$_] } (0 .. $#colnames) };
}
return \@ret;
}
}
- $self->throw_exception('Populate expects an arrayref of either hashrefs, arrayrefs, coderefs or arrayrefrefs');
+ $self->throw_exception('Populate expects an arrayref of hashrefs or arrayref of arrayrefs');
}
sub _normalize_populate_to_arrayref {