From: Rafael Kitover Date: Tue, 16 Mar 2010 00:15:45 +0000 (-0400) Subject: turn off cascade_delete/copy, set on_delete/update X-Git-Tag: 0.06000~50 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class-Schema-Loader.git;a=commitdiff_plain;h=53ef681d0209e2c85ddd60e049e3c8510fb27bb5 turn off cascade_delete/copy, set on_delete/update --- diff --git a/Changes b/Changes index 5374c13..ec5ecad 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,8 @@ Revision history for Perl extension DBIx::Class::Schema::Loader + - cascade_delete and cascade_copy are turned off for has_many/might_have + by default, and belongs_to has on_delete => 'CASCADE' and on_update => + 'CASCADE' by default, overridable via relationship_attrs - set inflate_datetime => 1 for 'AS getdate()' computed columns in Sybase - preliminary Firebird support diff --git a/lib/DBIx/Class/Schema/Loader/Manual/UpgradingFromV4.pod b/lib/DBIx/Class/Schema/Loader/Manual/UpgradingFromV4.pod index 391fafc..21dc9e3 100644 --- a/lib/DBIx/Class/Schema/Loader/Manual/UpgradingFromV4.pod +++ b/lib/DBIx/Class/Schema/Loader/Manual/UpgradingFromV4.pod @@ -28,6 +28,12 @@ It will also more correctly infer the relationship type, e.g. some relationships that were previously detected as a C will now be a C (when it detects a unique constraint on the foreign key column.) +Also C and C are turned off for by default for +C and C relationships, while C relationships +are created with C<< on_delete => 'CASCADE' >> and C<< on_update => 'CASCADE' >> +by default. This is overridable via +L. + =item * moniker_map diff --git a/lib/DBIx/Class/Schema/Loader/RelBuilder.pm b/lib/DBIx/Class/Schema/Loader/RelBuilder.pm index 0a86d60..359c9a7 100644 --- a/lib/DBIx/Class/Schema/Loader/RelBuilder.pm +++ b/lib/DBIx/Class/Schema/Loader/RelBuilder.pm @@ -156,15 +156,33 @@ sub _to_S { return Lingua::EN::Inflect::Number::to_S($name); } +sub _default_relationship_attrs { +{ + has_many => { + cascade_delete => 0, + cascade_copy => 0, + }, + might_have => { + cascade_delete => 0, + cascade_copy => 0, + }, + belongs_to => { + on_delete => 'CASCADE', + on_update => 'CASCADE', + }, +} } + # accessor for options to be passed to each generated relationship # type. take single argument, the relationship type name, and returns # either a hashref (if some options are set), or nothing sub _relationship_attrs { my ( $self, $reltype ) = @_; my $r = $self->{relationship_attrs}; - return unless $r && ( $r->{all} || $r->{$reltype} ); - my %composite = %{ $r->{all} || {} }; + my %composite = ( + %{ $self->_default_relationship_attrs->{$reltype} || {} }, + %{ $r->{all} || {} } + ); + if( my $specific = $r->{$reltype} ) { while( my ($k,$v) = each %$specific ) { $composite{$k} = $v; diff --git a/lib/DBIx/Class/Schema/Loader/RelBuilder/Compat/v0_040.pm b/lib/DBIx/Class/Schema/Loader/RelBuilder/Compat/v0_040.pm index adb5f30..cc2653c 100644 --- a/lib/DBIx/Class/Schema/Loader/RelBuilder/Compat/v0_040.pm +++ b/lib/DBIx/Class/Schema/Loader/RelBuilder/Compat/v0_040.pm @@ -6,6 +6,8 @@ use Class::C3; use base 'DBIx::Class::Schema::Loader::RelBuilder'; +sub _default_relationship_attrs { +{} } + sub _to_PL { my ($self, $name) = @_; diff --git a/t/backcompat/0.04006/lib/dbixcsl_common_tests.pm b/t/backcompat/0.04006/lib/dbixcsl_common_tests.pm index 7ab3f98..4d51475 100644 --- a/t/backcompat/0.04006/lib/dbixcsl_common_tests.pm +++ b/t/backcompat/0.04006/lib/dbixcsl_common_tests.pm @@ -43,7 +43,7 @@ sub _monikerize { sub run_tests { my $self = shift; - plan tests => 91; + plan tests => 99; $self->create(); @@ -255,7 +255,7 @@ sub run_tests { is( $obj2->id, 2 ); SKIP: { - skip $self->{skip_rels}, 52 if $self->{skip_rels}; + skip $self->{skip_rels}, 61 if $self->{skip_rels}; my $moniker3 = $monikers->{loader_test3}; my $class3 = $classes->{loader_test3}; @@ -354,6 +354,31 @@ sub run_tests { ok ($rsobj4->result_source->has_relationship('loader_test5_from_ids'), "rel with preposition 'from' and _id pluralized backward-compatibly"); + # check that default relationship attributes are not applied in 0.04006 mode + is $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{cascade_delete}, 1, + 'cascade_delete => 1 on has_many by default'; + + is $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{cascade_copy}, 1, + 'cascade_copy => 1 on has_many by default'; + + ok ((not exists $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{on_delete}), + 'has_many does not have on_delete'); + + ok ((not exists $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{on_update}), + 'has_many does not have on_update'); + + isnt $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{on_delete}, 'CASCADE', + "on_delete => 'CASCADE' not on belongs_to by default"; + + isnt $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{on_update}, 'CASCADE', + "on_update => 'CASCADE' not on belongs_to by default"; + + ok ((not exists $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{cascade_delete}), + 'belongs_to does not have cascade_delete'); + + ok ((not exists $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{cascade_copy}), + 'belongs_to does not have cascade_copy'); + # find on multi-col pk my $obj5 = $rsobj5->find({id1 => 1, id2 => 1}); is( $obj5->id2, 1 ); diff --git a/t/lib/dbixcsl_common_tests.pm b/t/lib/dbixcsl_common_tests.pm index 97de888..d8dc3f5 100644 --- a/t/lib/dbixcsl_common_tests.pm +++ b/t/lib/dbixcsl_common_tests.pm @@ -60,29 +60,6 @@ sub _monikerize { return undef; } -sub _custom_column_info { - my ( $table_name, $column_name, $column_info ) = @_; - - $table_name = lc ( $table_name ); - $column_name = lc ( $column_name ); - - if ( $table_name eq 'loader_test35' - and $column_name eq 'an_int' - ){ - return { is_numeric => 1 } - } - # Set inflate_datetime or inflate_date to check - # datetime_timezone and datetime_locale - if ( $table_name eq 'loader_test36' ){ - return { inflate_datetime => 1 } if - ( $column_name eq 'b_char_as_data' ); - return { inflate_date => 1 } if - ( $column_name eq 'c_char_as_data' ); - } - - return; -} - sub run_tests { my $self = shift; @@ -97,7 +74,7 @@ sub run_tests { } } - plan tests => @connect_info * (159 + ($self->{extra}->{count} || 0)); + plan tests => @connect_info * (171 + ($self->{extra}->{count} || 0)); foreach my $info_idx (0..$#connect_info) { my $info = $connect_info[$info_idx]; @@ -392,7 +369,7 @@ sub test_schema { ); SKIP: { - skip $self->{skip_rels}, 101 if $self->{skip_rels}; + skip $self->{skip_rels}, 113 if $self->{skip_rels}; my $moniker3 = $monikers->{loader_test3}; my $class3 = $classes->{loader_test3}; @@ -532,6 +509,43 @@ sub test_schema { ok ($rsobj4->result_source->has_relationship('loader_test5s_from'), "rel with preposition 'from' pluralized correctly"); + # check default relationship attributes + is $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{cascade_delete}, 0, + 'cascade_delete => 0 on has_many by default'; + + is $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{cascade_copy}, 0, + 'cascade_copy => 0 on has_many by default'; + + ok ((not exists $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{on_delete}), + 'has_many does not have on_delete'); + + ok ((not exists $rsobj3->result_source->relationship_info('loader_test4zes')->{attrs}{on_update}), + 'has_many does not have on_update'); + + is $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{on_delete}, 'CASCADE', + "on_delete => 'CASCADE' on belongs_to by default"; + + is $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{on_update}, 'CASCADE', + "on_update => 'CASCADE' on belongs_to by default"; + + ok ((not exists $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{cascade_delete}), + 'belongs_to does not have cascade_delete'); + + ok ((not exists $rsobj4->result_source->relationship_info('fkid_singular')->{attrs}{cascade_copy}), + 'belongs_to does not have cascade_copy'); + + is $rsobj27->result_source->relationship_info('loader_test28')->{attrs}{cascade_delete}, 0, + 'cascade_delete => 0 on might_have by default'; + + is $rsobj27->result_source->relationship_info('loader_test28')->{attrs}{cascade_copy}, 0, + 'cascade_copy => 0 on might_have by default'; + + ok ((not exists $rsobj27->result_source->relationship_info('loader_test28')->{attrs}{on_delete}), + 'might_have does not have on_delete'); + + ok ((not exists $rsobj27->result_source->relationship_info('loader_test28')->{attrs}{on_update}), + 'might_have does not have on_update'); + # find on multi-col pk my $obj5 = eval { $rsobj5->find({id1 => 1, iD2 => 1}) } || @@ -1448,6 +1462,29 @@ sub drop_tables { $dbh->disconnect; } +sub _custom_column_info { + my ( $table_name, $column_name, $column_info ) = @_; + + $table_name = lc ( $table_name ); + $column_name = lc ( $column_name ); + + if ( $table_name eq 'loader_test35' + and $column_name eq 'an_int' + ){ + return { is_numeric => 1 } + } + # Set inflate_datetime or inflate_date to check + # datetime_timezone and datetime_locale + if ( $table_name eq 'loader_test36' ){ + return { inflate_datetime => 1 } if + ( $column_name eq 'b_char_as_data' ); + return { inflate_date => 1 } if + ( $column_name eq 'c_char_as_data' ); + } + + return; +} + sub DESTROY { my $self = shift; unless ($ENV{SCHEMA_LOADER_TESTS_NOCLEANUP}) {