X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FRow.pm;h=bb72a3a6d821bfc5e832abc2ac2f66f000d7f890;hb=70ecd5a103ed5ab8f674df100da40ff47d4ae658;hp=3d2638d2b7aa4302b310f3837f9f8299f738b8d9;hpb=00400cf367e0dbe486ea95aaedbee1296353f515;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index 3d2638d..bb72a3a 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -66,6 +66,7 @@ sub insert { $source->storage->insert($source->from, { $self->get_columns }); $self->in_storage(1); $self->{_dirty_columns} = {}; + $self->{related_resultsets} = {}; return $self; } @@ -110,6 +111,7 @@ sub update { $self->throw_exception("Can't update ${self}: updated more than one row"); } $self->{_dirty_columns} = {}; + $self->{related_resultsets} = {}; return $self; } @@ -237,9 +239,26 @@ Inserts a new row with the specified changes. sub copy { my ($self, $changes) = @_; - my $new = bless({ _column_data => { %{$self->{_column_data}}} }, ref $self); + $changes ||= {}; + my $col_data = { %{$self->{_column_data}} }; + foreach my $col (keys %$col_data) { + delete $col_data->{$col} + if $self->result_source->column_info($col)->{is_auto_increment}; + } + my $new = bless({ _column_data => $col_data }, ref $self); $new->set_column($_ => $changes->{$_}) for keys %$changes; - return $new->insert; + $new->insert; + foreach my $rel ($self->result_source->relationships) { + my $rel_info = $self->result_source->relationship_info($rel); + if ($rel_info->{attrs}{cascade_copy}) { + my $resolved = $self->result_source->resolve_condition( + $rel_info->{cond}, $rel, $new); + foreach my $related ($self->search_related($rel)) { + $related->copy($resolved); + } + } + } + $new; } =head2 store_column @@ -276,25 +295,35 @@ sub inflate_result { }, ref $class || $class); my $schema; - PRE: foreach my $pre (keys %{$prefetch||{}}) { - my $pre_source = $source->related_source($pre); - $class->throw_exception("Can't prefetch non-existant relationship ${pre}") unless $pre_source; - my $fetched; - unless ($pre_source->primary_columns == grep { exists $prefetch->{$pre}[0]{$_} - and !defined $prefetch->{$pre}[0]{$_} } $pre_source->primary_columns) - { - $fetched = $pre_source->result_class->inflate_result( - $pre_source, @{$prefetch->{$pre}}); + foreach my $pre (keys %{$prefetch||{}}) { + my $pre_val = $prefetch->{$pre}; + # if first prefetch item is arrayref, assume this is a has_many prefetch + # and that objects are pre inflated (TODO: check arrayref contents using "ref" to make sure) + if( ref $pre_val->[0] eq 'ARRAY' ) { + $new->related_resultset($pre)->set_cache( $pre_val->[0] ); } - my $accessor = $source->relationship_info($pre)->{attrs}{accessor}; - $class->throw_exception("No accessor for prefetched $pre") - unless defined $accessor; - if ($accessor eq 'single') { - $new->{_relationship_data}{$pre} = $fetched; - } elsif ($accessor eq 'filter') { - $new->{_inflated_column}{$pre} = $fetched; - } else { - $class->throw_exception("Don't know how to store prefetched $pre"); + else { + my $pre_source = $source->related_source($pre); + $class->throw_exception("Can't prefetch non-existent relationship ${pre}") unless $pre_source; + my $fetched; + unless ($pre_source->primary_columns == grep { exists $prefetch->{$pre}[0]{$_} + and !defined $prefetch->{$pre}[0]{$_} } $pre_source->primary_columns) + { + $fetched = $pre_source->result_class->inflate_result( + $pre_source, @{$prefetch->{$pre}}); + } + my $accessor = $source->relationship_info($pre)->{attrs}{accessor}; + $class->throw_exception("No accessor for prefetched $pre") + unless defined $accessor; + if ($accessor eq 'single') { + $new->{_relationship_data}{$pre} = $fetched; + } elsif ($accessor eq 'filter') { + $new->{_inflated_column}{$pre} = $fetched; + } elsif ($accessor eq 'multi') { + $class->throw_exception("Cache must be enabled for has_many prefetch '$pre'"); + } else { + $class->throw_exception("Prefetch not supported with accessor '$accessor'"); + } } } return $new;