X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=lib%2FDBIx%2FClass%2FRow.pm;h=341ab296aca0ca10c92895c07956406e71de979c;hb=e60dc79fcd4d6318e83584b826526e65048b86a9;hp=e5fb4c9ecc97cfd3a0e9914d34486c7341956af5;hpb=9c6d6d935cf5ef946fafec02a33a3d2415ba706f;p=dbsrgits%2FDBIx-Class.git diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index e5fb4c9..341ab29 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -48,7 +48,9 @@ sub new { my ($class, $attrs) = @_; $class = ref $class if ref $class; - my $new = { _column_data => {} }; + my $new = { + _column_data => {}, + }; bless $new, $class; if (my $handle = delete $attrs->{-source_handle}) { @@ -76,8 +78,10 @@ sub new { my $rel_obj = delete $attrs->{$key}; if(!Scalar::Util::blessed($rel_obj)) { $rel_obj = $new->find_or_new_related($key, $rel_obj); - $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage); } + + $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage); + $new->set_from_related($key, $rel_obj); $related->{$key} = $rel_obj; next; @@ -90,6 +94,8 @@ sub new { $rel_obj = $new->new_related($key, $rel_obj); $new->{_rel_in_storage} = 0; } + + $new->{_rel_in_storage} = 0 unless ($rel_obj->in_storage); } $related->{$key} = $others; next; @@ -150,9 +156,7 @@ sub insert { my %related_stuff = (%{$self->{_relationship_data} || {}}, %{$self->{_inflated_column} || {}}); - if(!$self->{_rel_in_storage}) - { - + if(!$self->{_rel_in_storage}) { $source->storage->txn_begin; # The guard will save us if we blow out of this scope via die @@ -166,24 +170,38 @@ sub insert { my @pri = $self->primary_columns; REL: foreach my $relname (keys %related_stuff) { - my $keyhash = $source->resolve_condition( - $source->relationship_info($relname)->{cond}, - undef, 1 - ); # the above argset gives me the dependent cols on self + + my $rel_obj = $related_stuff{$relname}; + + next REL unless (Scalar::Util::blessed($rel_obj) + && $rel_obj->isa('DBIx::Class::Row')); + + my $cond = $source->relationship_info($relname)->{cond}; + + next REL unless ref($cond) eq 'HASH'; + + # map { foreign.foo => 'self.bar' } to { bar => 'foo' } + + my $keyhash = { map { my $x = $_; $x =~ s/.*\.//; $x; } reverse %$cond }; # assume anything that references our PK probably is dependent on us - # rather than vice versa + # rather than vice versa, unless the far side is (a) defined or (b) + # auto-increment foreach my $p (@pri) { - next REL if exists $keyhash->{$p}; + if (exists $keyhash->{$p}) { + warn $keyhash->{$p}; + unless (defined($rel_obj->get_column($keyhash->{$p})) + || $rel_obj->column_info($keyhash->{$p}) + ->{is_auto_increment}) { + next REL; + } + } } - my $rel_obj = $related_stuff{$relname}; - if(Scalar::Util::blessed($rel_obj) && $rel_obj->isa('DBIx::Class::Row')) { - $rel_obj->insert(); - $self->set_from_related($relname, $rel_obj); - delete $related_stuff{$relname}; - } + $rel_obj->insert(); + $self->set_from_related($relname, $rel_obj); + delete $related_stuff{$relname}; } } @@ -208,8 +226,7 @@ sub insert { $self->store_column($auto_pri[$_] => $ids[$_]) for 0 .. $#ids; } - if(!$self->{_rel_in_storage}) - { + if(!$self->{_rel_in_storage}) { ## Now do the has_many rels, that need $selfs ID. foreach my $relname (keys %related_stuff) { my $rel_obj = $related_stuff{$relname}; @@ -471,6 +488,10 @@ sub set_column { my $ret = $self->store_column(@_); $self->{_dirty_columns}{$column} = 1 if (defined $old ^ defined $ret) || (defined $old && $old ne $ret); + + # XXX clear out the relation cache for this column + delete $self->{related_resultsets}{$column}; + return $ret; }