From: D. Ilmari Mannsåker Date: Mon, 16 Sep 2013 11:19:09 +0000 (+0100) Subject: Skip many_to_many bridges involving might_have relationships X-Git-Tag: 0.07036_02~3 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits%2FDBIx-Class-Schema-Loader.git;a=commitdiff_plain;h=e3c0a681dd2a328998f4176c2a3cca364295b771 Skip many_to_many bridges involving might_have relationships If one or both of the relationsips is a one-to-one relatiohip, the bridge should be one-to-many or one-to-one, respectively. However, DBIx::Class doesn't support such bridges, so skip them for now, keeping the option open to add support if/when DBIC does, without having to worry about back-compat shenanigans. This reverts commit b0cdc8a5bc6db9206a53e52bd9c868ba8442ca2b and fixes the crash differently. --- diff --git a/Changes b/Changes index b5de9cb..13d40d1 100644 --- a/Changes +++ b/Changes @@ -1,5 +1,7 @@ Revision history for Perl extension DBIx::Class::Schema::Loader + - Skip many_to_many bridges involving might_have relationships + 0.07036_01 2013-08-11 - Fix typos in POD and comments (RT#87644) - Don't ship MYMETA.* files (RT#87713) diff --git a/lib/DBIx/Class/Schema/Loader/RelBuilder.pm b/lib/DBIx/Class/Schema/Loader/RelBuilder.pm index de3dce1..dbcacf2 100644 --- a/lib/DBIx/Class/Schema/Loader/RelBuilder.pm +++ b/lib/DBIx/Class/Schema/Loader/RelBuilder.pm @@ -514,15 +514,19 @@ sub _generate_m2ms { my $class2 = $rels->[1]{args}[1]; my $class1_to_link_table_rel = first { - $_->{method} =~ /\A(?:has_many|might_have)\z/ && $_->{args}[1] eq $class + $_->{method} eq 'has_many' && $_->{args}[1] eq $class } @{ $all_code->{$class1} }; + next unless $class1_to_link_table_rel; + my $class1_to_link_table_rel_name = $class1_to_link_table_rel->{args}[0]; my $class2_to_link_table_rel = first { - $_->{method} =~ /\A(?:has_many|might_have)\z/ && $_->{args}[1] eq $class + $_->{method} eq 'has_many' && $_->{args}[1] eq $class } @{ $all_code->{$class2} }; + next unless $class2_to_link_table_rel; + my $class2_to_link_table_rel_name = $class2_to_link_table_rel->{args}[0]; my $class1_link_rel = $rels->[1]{args}[0]; diff --git a/t/lib/dbixcsl_common_tests.pm b/t/lib/dbixcsl_common_tests.pm index c80c52c..9c92e07 100644 --- a/t/lib/dbixcsl_common_tests.pm +++ b/t/lib/dbixcsl_common_tests.pm @@ -119,7 +119,7 @@ sub run_tests { $num_rescans++ if $self->{vendor} eq 'Firebird'; plan tests => @connect_info * - (223 + $num_rescans * $col_accessor_map_tests + $extra_count + ($self->{data_type_tests}{test_count} || 0)); + (228 + $num_rescans * $col_accessor_map_tests + $extra_count + ($self->{data_type_tests}{test_count} || 0)); foreach my $info_idx (0..$#connect_info) { my $info = $connect_info[$info_idx]; @@ -284,7 +284,7 @@ sub setup_schema { my $standard_sources = not defined $expected_count; if ($standard_sources) { - $expected_count = 37; + $expected_count = 38; if (not ($self->{vendor} eq 'mssql' && $connect_info->[0] =~ /Sybase/)) { $expected_count++ for @{ $self->{data_type_tests}{table_names} || [] }; @@ -723,6 +723,10 @@ qr/\n__PACKAGE__->load_components\("TestSchemaComponent", "\+TestSchemaComponent my $class36 = $classes->{loader_test36}; my $rsobj36 = $conn->resultset($moniker36); + my $moniker37 = $monikers->{loader_test37}; + my $class37 = $classes->{loader_test37}; + my $rsobj37 = $conn->resultset($moniker37); + isa_ok( $rsobj3, "DBIx::Class::ResultSet" ); isa_ok( $rsobj4, "DBIx::Class::ResultSet" ); isa_ok( $rsobj5, "DBIx::Class::ResultSet" ); @@ -747,6 +751,7 @@ qr/\n__PACKAGE__->load_components\("TestSchemaComponent", "\+TestSchemaComponent isa_ok( $rsobj33, "DBIx::Class::ResultSet" ); isa_ok( $rsobj34, "DBIx::Class::ResultSet" ); isa_ok( $rsobj36, "DBIx::Class::ResultSet" ); + isa_ok( $rsobj37, "DBIx::Class::ResultSet" ); # basic rel test my $obj4 = try { $rsobj4->find(123) } || $rsobj4->search({ id => 123 })->single; @@ -928,16 +933,22 @@ qr/\n__PACKAGE__->(?:belongs_to|has_many|might_have|has_one|many_to_many)\( ok($m2m = (try { $class18->_m2m_metadata->{children} }), 'many_to_many created'); - is $m2m->{relation}, 'loader_test20s', 'm2m near has_many rel'; + is $m2m->{relation}, 'loader_test20s', 'm2m near rel'; is $m2m->{foreign_relation}, 'child', 'm2m far rel'; is $m2m->{attrs}->{order_by}, 'me.id', 'm2m bridge attrs'; ok($m2m = (try { $class19->_m2m_metadata->{parents} }), 'many_to_many created'); - is $m2m->{relation}, 'loader_test20', 'm2m near might_have rel'; + is $m2m->{relation}, 'loader_test20s', 'm2m near rel'; is $m2m->{foreign_relation}, 'parent', 'm2m far rel'; is $m2m->{attrs}->{order_by}, 'me.id', 'm2m bridge attrs'; + ok( $class37->relationship_info('parent'), 'parents rel created' ); + ok( $class37->relationship_info('child'), 'child rel created' ); + + is_deeply($class32->_m2m_metadata, {}, 'many_to_many not created for might_have'); + is_deeply($class34->_m2m_metadata, {}, 'many_to_many not created for might_have'); + # test double multi-col fk 26 -> 25 my $obj26 = try { $rsobj26->find(33) } || $rsobj26->search({ id => 33 })->single; @@ -1726,7 +1737,7 @@ sub create { qq{ CREATE TABLE loader_test20 ( parent INTEGER NOT NULL, - child INTEGER NOT NULL UNIQUE, + child INTEGER NOT NULL, PRIMARY KEY (parent, child), FOREIGN KEY (parent) REFERENCES loader_test18 (id), FOREIGN KEY (child) REFERENCES loader_test19 (id) @@ -1854,6 +1865,17 @@ sub create { ) $self->{innodb} }, q{ INSERT INTO loader_test34 (id,rel1,rel2) VALUES (1,2,2) }, + + qq{ + CREATE TABLE loader_test37 ( + parent INTEGER NOT NULL, + child INTEGER NOT NULL UNIQUE, + PRIMARY KEY (parent, child), + FOREIGN KEY (parent) REFERENCES loader_test32 (id), + FOREIGN KEY (child) REFERENCES loader_test34 (id) + ) $self->{innodb} + }, + q{ INSERT INTO loader_test37 (parent, child) VALUES (1,1) }, ); @statements_advanced = ( @@ -2046,6 +2068,7 @@ sub drop_tables { loader_test28 loader_test29 loader_test27 + loader_test37 loader_test32 loader_test31 loader_test34