From: Matt S Trout Date: Tue, 14 Feb 2006 18:52:28 +0000 (+0000) Subject: added cascade_copy relationship attribute X-Git-Tag: v0.06000~61^2~29 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=333cce60480be0ebce201d37e2bfb18601b54404;p=dbsrgits%2FDBIx-Class.git added cascade_copy relationship attribute --- diff --git a/Changes b/Changes index de60b28..e051591 100644 --- a/Changes +++ b/Changes @@ -1,7 +1,10 @@ Revision history for DBIx::Class + - added cascade_copy relationship attribute + (sponsored by Airspace Software, http://www.airspace.co.uk/) - clean up set_from_related - made copy() automatically null out auto-inc columns + - remove dependency on Module::Find in 40resultsetmanager.t (RT #17598) - Another fix for count with scalar group_by. 0.05005 2006-02-13 21:24:51 diff --git a/lib/DBIx/Class/Relationship/HasMany.pm b/lib/DBIx/Class/Relationship/HasMany.pm index 716c292..1e61c74 100644 --- a/lib/DBIx/Class/Relationship/HasMany.pm +++ b/lib/DBIx/Class/Relationship/HasMany.pm @@ -35,6 +35,7 @@ sub has_many { { accessor => 'multi', join_type => 'LEFT', cascade_delete => 1, + cascade_copy => 1, %{$attrs||{}} } ); } diff --git a/lib/DBIx/Class/Row.pm b/lib/DBIx/Class/Row.pm index 9128599..0d4a8a4 100644 --- a/lib/DBIx/Class/Row.pm +++ b/lib/DBIx/Class/Row.pm @@ -236,6 +236,7 @@ Inserts a new row with the specified changes. sub copy { my ($self, $changes) = @_; + $changes ||= {}; my $col_data = { %{$self->{_column_data}} }; foreach my $col (keys %$col_data) { delete $col_data->{$col} @@ -243,7 +244,18 @@ sub copy { } 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 diff --git a/t/basicrels/22cascade_copy.t b/t/basicrels/22cascade_copy.t new file mode 100644 index 0000000..c670152 --- /dev/null +++ b/t/basicrels/22cascade_copy.t @@ -0,0 +1,7 @@ +use Test::More; +use lib qw(t/lib); +use DBICTest; +use DBICTest::BasicRels; + +require "t/run/22cascade_copy.tl"; +run_tests(DBICTest->schema); diff --git a/t/helperrels/22cascade_copy.t b/t/helperrels/22cascade_copy.t new file mode 100644 index 0000000..bc124e1 --- /dev/null +++ b/t/helperrels/22cascade_copy.t @@ -0,0 +1,7 @@ +use Test::More; +use lib qw(t/lib); +use DBICTest; +use DBICTest::HelperRels; + +require "t/run/22cascade_copy.tl"; +run_tests(DBICTest->schema); diff --git a/t/lib/DBICTest/Schema/Artist.pm b/t/lib/DBICTest/Schema/Artist.pm index 2200cd4..d05526f 100644 --- a/t/lib/DBICTest/Schema/Artist.pm +++ b/t/lib/DBICTest/Schema/Artist.pm @@ -2,6 +2,8 @@ package DBICTest::Schema::Artist; use base 'DBIx::Class::Core'; +__PACKAGE__->load_components('PK::Auto'); + DBICTest::Schema::Artist->table('artist'); DBICTest::Schema::Artist->add_columns( 'artistid' => { diff --git a/t/lib/DBICTest/Schema/BasicRels.pm b/t/lib/DBICTest/Schema/BasicRels.pm index 7a6f520..2a4942c 100644 --- a/t/lib/DBICTest/Schema/BasicRels.pm +++ b/t/lib/DBICTest/Schema/BasicRels.pm @@ -5,11 +5,12 @@ use base 'DBIx::Class::Core'; DBICTest::Schema::Artist->add_relationship( cds => 'DBICTest::Schema::CD', { 'foreign.artist' => 'self.artistid' }, - { order_by => 'year', join_type => 'LEFT', cascade_delete => 1 } + { order_by => 'year', join_type => 'LEFT', cascade_delete => 1, cascade_copy => 1 } ); DBICTest::Schema::Artist->add_relationship( twokeys => 'DBICTest::Schema::TwoKeys', - { 'foreign.artist' => 'self.artistid' } + { 'foreign.artist' => 'self.artistid' }, + { cascade_copy => 1 } ); DBICTest::Schema::Artist->add_relationship( onekeys => 'DBICTest::Schema::OneKey', @@ -37,7 +38,7 @@ DBICTest::Schema::CD->add_relationship( DBICTest::Schema::CD->add_relationship( tags => 'DBICTest::Schema::Tag', { 'foreign.cd' => 'self.cdid' }, - { join_type => 'LEFT', cascade_delete => 1 } + { join_type => 'LEFT', cascade_delete => 1, cascade_copy => 1 } ); #DBICTest::Schema::CD->might_have(liner_notes => 'DBICTest::Schema::LinerNotes' => qw/notes/); DBICTest::Schema::CD->add_relationship( diff --git a/t/lib/DBICTest/Schema/CD.pm b/t/lib/DBICTest/Schema/CD.pm index 8e04c16..4eaba4f 100644 --- a/t/lib/DBICTest/Schema/CD.pm +++ b/t/lib/DBICTest/Schema/CD.pm @@ -2,6 +2,8 @@ package DBICTest::Schema::CD; use base 'DBIx::Class::Core'; +__PACKAGE__->load_components('PK::Auto'); + DBICTest::Schema::CD->table('cd'); DBICTest::Schema::CD->add_columns( 'cdid' => { diff --git a/t/lib/DBICTest/Schema/HelperRels.pm b/t/lib/DBICTest/Schema/HelperRels.pm index ff47640..1fb8886 100644 --- a/t/lib/DBICTest/Schema/HelperRels.pm +++ b/t/lib/DBICTest/Schema/HelperRels.pm @@ -42,7 +42,8 @@ DBICTest::Schema::CD_to_Producer->belongs_to( ); DBICTest::Schema::Artist->has_many( 'artist_undirected_maps', 'DBICTest::Schema::ArtistUndirectedMap', - [{'foreign.id1' => 'self.artistid'}, {'foreign.id2' => 'self.artistid'}] + [{'foreign.id1' => 'self.artistid'}, {'foreign.id2' => 'self.artistid'}], + { cascade_copy => 0 } # this would *so* not make sense ); DBICTest::Schema::ArtistUndirectedMap->belongs_to( 'artist1', 'DBICTest::Schema::Artist', 'id1'); diff --git a/t/lib/DBICTest/Schema/OneKey.pm b/t/lib/DBICTest/Schema/OneKey.pm index 081c94b..19387eb 100644 --- a/t/lib/DBICTest/Schema/OneKey.pm +++ b/t/lib/DBICTest/Schema/OneKey.pm @@ -2,6 +2,8 @@ package DBICTest::Schema::OneKey; use base 'DBIx::Class::Core'; +__PACKAGE__->load_components('PK::Auto'); + DBICTest::Schema::OneKey->table('onekey'); DBICTest::Schema::OneKey->add_columns( 'id' => { diff --git a/t/lib/DBICTest/Schema/Tag.pm b/t/lib/DBICTest/Schema/Tag.pm index 0a303d6..5b4eb20 100644 --- a/t/lib/DBICTest/Schema/Tag.pm +++ b/t/lib/DBICTest/Schema/Tag.pm @@ -2,10 +2,12 @@ package DBICTest::Schema::Tag; use base qw/DBIx::Class::Core/; +__PACKAGE__->load_components('PK::Auto'); + DBICTest::Schema::Tag->table('tags'); DBICTest::Schema::Tag->add_columns( 'tagid' => { - data_type => 'varchar', + data_type => 'integer', is_auto_increment => 1, }, 'cd' => { diff --git a/t/lib/sqlite.sql b/t/lib/sqlite.sql index 8015b29..f6060fe 100644 --- a/t/lib/sqlite.sql +++ b/t/lib/sqlite.sql @@ -1,6 +1,6 @@ -- -- Created by SQL::Translator::Producer::SQLite --- Created on Mon Feb 6 01:07:16 2006 +-- Created on Tue Feb 14 16:16:19 2006 -- BEGIN TRANSACTION; @@ -117,10 +117,9 @@ CREATE TABLE treelike ( -- Table: tags -- CREATE TABLE tags ( - tagid varchar NOT NULL, + tagid INTEGER PRIMARY KEY NOT NULL, cd integer NOT NULL, - tag varchar NOT NULL, - PRIMARY KEY (tagid) + tag varchar NOT NULL ); -- diff --git a/t/run/22cascade_copy.tl b/t/run/22cascade_copy.tl new file mode 100644 index 0000000..8c682e5 --- /dev/null +++ b/t/run/22cascade_copy.tl @@ -0,0 +1,23 @@ +use strict; +use warnings; + +sub run_tests { +my $schema = shift; + +plan tests => 4; +my $artist = $schema->resultset('Artist')->find(1); +my $artist_cds = $artist->search_related('cds'); +my $cover_band = $artist->copy; +my $cover_cds = $cover_band->search_related('cds'); +cmp_ok($cover_band->id, '!=', $artist->id, 'ok got new column id...'); +is($cover_cds->count, $artist_cds->count, 'duplicated rows count ok'); + +#check multi-keyed +cmp_ok($cover_band->search_related('twokeys')->count, '>', 0, 'duplicated multiPK ok'); + +#and check copying a few relations away +cmp_ok($cover_cds->search_related('tags')->count, '==', + $artist_cds->search_related('tags')->count , 'duplicated count ok'); + +} +1;