From: Matt S Trout Date: Fri, 20 Feb 2009 04:42:18 +0000 (+0000) Subject: Merge 'trunk' into 'multi_stuff' X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=f847f84d07ac96caaaf1142174fe01bf017da567;hp=175c5bafdea904aa0124aea179154ce11e621fbf;p=dbsrgits%2FDBIx-Class-Historic.git Merge 'trunk' into 'multi_stuff' r27901@agaton (orig r5562): robkinyon | 2009-02-20 04:37:12 +0000 r5547@rkinyon-lt-osx (orig r5546): robkinyon | 2009-02-19 23:29:39 -0500 Added qualifiers as to when as_query will work --- diff --git a/lib/DBIx/Class/ResultSet.pm b/lib/DBIx/Class/ResultSet.pm index 28b2f9a..92cbbd7 100644 --- a/lib/DBIx/Class/ResultSet.pm +++ b/lib/DBIx/Class/ResultSet.pm @@ -1701,6 +1701,7 @@ sub new_result { && $self->{cond} eq $DBIx::Class::ResultSource::UNRESOLVABLE_CONDITION ) { %new = %{$self->{attrs}{related_objects}}; + $new{-from_resultset} = [ keys %new ] if keys %new; } else { $self->throw_exception( "Can't abstract implicit construct, condition not a hash" diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index abc34ab..7b22897 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -131,6 +131,10 @@ sub new { $new->result_source($source); } + if (my $related = delete $attrs->{-from_resultset}) { + @{$new->{_ignore_at_insert}={}}{@$related} = (); + } + if ($attrs) { $new->throw_exception("attrs must be a hashref") unless ref($attrs) eq 'HASH'; @@ -156,7 +160,7 @@ sub new { $new->set_from_related($key, $rel_obj); } else { $new->{_rel_in_storage} = 0; - MULTICREATE_DEBUG and warn "MC $new: uninserted $key $rel_obj\n"; + MULTICREATE_DEBUG and warn "MC $new uninserted $key $rel_obj\n"; } $related->{$key} = $rel_obj; @@ -178,7 +182,7 @@ sub new { } else { $new->{_rel_in_storage} = 0; MULTICREATE_DEBUG and - warn "MC $new: uninserted $key $rel_obj ($idx of $total)\n"; + warn "MC $new uninserted $key $rel_obj (${\($idx+1)} of $total)\n"; } $new->set_from_related($key, $rel_obj) if $rel_obj->in_storage; push(@objects, $rel_obj); @@ -195,7 +199,7 @@ sub new { } unless ($rel_obj->in_storage) { $new->{_rel_in_storage} = 0; - MULTICREATE_DEBUG and warn "MC $new: uninserted $key $rel_obj"; + MULTICREATE_DEBUG and warn "MC $new uninserted $key $rel_obj"; } $inflated->{$key} = $rel_obj; next; @@ -288,7 +292,10 @@ sub insert { } } - MULTICREATE_DEBUG and warn "MC $self inserting self\n"; + MULTICREATE_DEBUG and do { + no warnings 'uninitialized'; + warn "MC $self inserting (".join(', ', $self->get_columns).")\n"; + }; my $updated_cols = $source->storage->insert($source, { $self->get_columns }); foreach my $col (keys %$updated_cols) { $self->store_column($col, $updated_cols->{$col}); @@ -319,7 +326,7 @@ sub insert { $self->{related_resultsets} = {}; if(!$self->{_rel_in_storage}) { - ## Now do the has_many rels, that need $selfs ID. + ## Now do the relationships that need our ID (has_many etc.) foreach my $relname (keys %related_stuff) { my $rel_obj = $related_stuff{$relname}; my @cands; @@ -335,10 +342,14 @@ sub insert { $obj->set_from_related($_, $self) for keys %$reverse; my $them = { %{$obj->{_relationship_data} || {} }, $obj->get_inflated_columns }; if ($self->__their_pk_needs_us($relname, $them)) { - MULTICREATE_DEBUG and warn "MC $self re-creating $relname $obj"; - my $re = $self->find_or_create_related($relname, $them); - $obj->{_column_data} = $re->{_column_data}; - MULTICREATE_DEBUG and warn "MC $self new $relname $obj"; + if (exists $self->{_ignore_at_insert}{$relname}) { + MULTICREATE_DEBUG and warn "MC $self skipping post-insert on $relname"; + } else { + MULTICREATE_DEBUG and warn "MC $self re-creating $relname $obj"; + my $re = $self->find_or_create_related($relname, $them); + %{$obj} = %{$re}; + MULTICREATE_DEBUG and warn "MC $self new $relname $obj"; + } } else { MULTICREATE_DEBUG and warn "MC $self post-inserting $obj"; $obj->insert(); @@ -346,6 +357,7 @@ sub insert { } } } + delete $self->{_ignore_at_insert}; $rollback_guard->commit; } diff --git a/t/96multi_create.t b/t/96multi_create.t index 9c75cac..d808eba 100644 --- a/t/96multi_create.t +++ b/t/96multi_create.t @@ -6,7 +6,7 @@ use Test::Exception; use lib qw(t/lib); use DBICTest; -plan tests => 85; +plan tests => 77; my $schema = DBICTest->init_schema(); @@ -513,9 +513,6 @@ eval { }; diag $@ if $@; -TODO: { -local $TODO = 'Next 2 evals are NOT supposed to work, jnaps code will be torn to bits in another branch'; -#SPECIAL_CASE eval { my $kurt_cobain = { name => 'Kurt Cobain' }; @@ -536,7 +533,8 @@ eval { }; diag $@ if $@; -#SPECIAL_CASE2 +=pod +# This test case has been moved to t/96multi_create/cd_single.t eval { my $pink_floyd = { name => 'Pink Floyd' }; @@ -552,10 +550,11 @@ eval { is($a->cds && $a->cds->first->title, 'The Wall', 'CD insertion ok'); }; diag $@ if $@; -} - +=cut diag '* Create foreign key col obj including PK (See test 20 in 66relationships.t)'; +## Create foreign key col obj including PK +## See test 20 in 66relationships.t eval { my $new_cd_hashref = { cdid => 27, diff --git a/t/96multi_create_new.t b/t/96multi_create_new.t index 909419f..3d7c1f1 100644 --- a/t/96multi_create_new.t +++ b/t/96multi_create_new.t @@ -6,7 +6,7 @@ use Test::Exception; use lib qw(t/lib); use DBICTest; -plan 'no_plan'; +plan tests => 9; my $schema = DBICTest->init_schema(); @@ -22,28 +22,42 @@ my $schema = DBICTest->init_schema(); # to new(). All other objects should be insert()able afterwards too. -my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode' }); -my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave in Silence', 'year' => 1982}); -eval { - $new_artist->insert; - $new_related_cd->insert; -}; -is ($@, '', 'Staged insertion successful'); -ok($new_artist->in_storage, 'artist inserted'); -ok($new_related_cd->in_storage, 'new_related_cd inserted'); - - -my $new_cd = $schema->resultset("CD")->new_result({}); -my $new_related_artist = $new_cd->new_related('artist', { 'name' => 'Marillion',}); -lives_ok ( - sub { - $new_related_artist->insert; - $new_cd->title( 'Misplaced Childhood' ); - $new_cd->year ( 1985 ); - $new_cd->artist( $new_related_artist ); # For exact backward compatibility - $new_cd->insert; - }, - 'Reversed staged insertion successful' -); -ok($new_related_artist->in_storage, 'related artist inserted'); -ok($new_cd->in_storage, 'cd inserted'); +{ + my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode' }); + my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave in Silence', 'year' => 1982}); + eval { + $new_artist->insert; + $new_related_cd->insert; + }; + is ($@, '', 'Staged insertion successful'); + ok($new_artist->in_storage, 'artist inserted'); + ok($new_related_cd->in_storage, 'new_related_cd inserted'); +} + +{ + my $new_artist = $schema->resultset("Artist")->new_result({ 'name' => 'Depeche Mode' }); + my $new_related_cd = $new_artist->new_related('cds', { 'title' => 'Leave in Silence', 'year' => 1982}); + eval { + $new_related_cd->insert; + }; + is ($@, '', 'CD insertion survives by inserting artist'); + ok($new_artist->in_storage, 'artist inserted'); + ok($new_related_cd->in_storage, 'new_related_cd inserted'); +} + +{ + my $new_cd = $schema->resultset("CD")->new_result({}); + my $new_related_artist = $new_cd->new_related('artist', { 'name' => 'Marillion',}); + lives_ok ( + sub { + $new_related_artist->insert; + $new_cd->title( 'Misplaced Childhood' ); + $new_cd->year ( 1985 ); + $new_cd->artist( $new_related_artist ); # For exact backward compatibility + $new_cd->insert; + }, + 'Reversed staged insertion successful' + ); + ok($new_related_artist->in_storage, 'related artist inserted'); + ok($new_cd->in_storage, 'cd inserted'); +}