initial merge of Schwern's CDBICompat work, with many thanks
[dbsrgits/DBIx-Class.git] / lib / DBIx / Class / Row.pm
index 332171a..341ab29 100644 (file)
@@ -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;
@@ -164,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};
     }
   }
 
@@ -468,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;
 }