From: Alexander Hartmaier Date: Fri, 26 Nov 2010 16:13:35 +0000 (+0100) Subject: Fix deploy and relationship traversal on partial schemas X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5b9ecfccf4d159b155c80fff6f12b701651f9f09;p=dbsrgits%2FDBIx-Class-Historic.git Fix deploy and relationship traversal on partial schemas --- diff --git a/Changes b/Changes index 2340424..ce5c4a9 100644 --- a/Changes +++ b/Changes @@ -14,6 +14,8 @@ Revision history for DBIx::Class - Fix incorrect error detection during populate() on Oracle - Better handling of result_source-less row objects by auto-calling result_source_instance when necessary + - Fix reverse_relationship_info and sqlt deploy on partially + loaded schemas (relationships point to non-existent sources) 0.08126_01 2011-01-14 14:00 (UTC) * New Features / Changes diff --git a/lib/DBIx/Class/ResultSource.pm b/lib/DBIx/Class/ResultSource.pm index 1dca0a6..9468e95 100644 --- a/lib/DBIx/Class/ResultSource.pm +++ b/lib/DBIx/Class/ResultSource.pm @@ -1345,11 +1345,14 @@ sub reverse_relationship_info { my @otherrels = $othertable->relationships(); my $otherrelationship; foreach my $otherrel (@otherrels) { - my $otherrel_info = $othertable->relationship_info($otherrel); + # this may be a partial schema with the related source not being + # available at all + my $back = try { $othertable->related_source($otherrel) } or next; - my $back = $othertable->related_source($otherrel); + # did we get back to ourselves? next unless $back->source_name eq $self->source_name; + my $otherrel_info = $othertable->relationship_info($otherrel); my @othertestconds; if (ref $otherrel_info->{cond} eq 'HASH') { diff --git a/lib/SQL/Translator/Parser/DBIx/Class.pm b/lib/SQL/Translator/Parser/DBIx/Class.pm index aa22b05..af8e117 100644 --- a/lib/SQL/Translator/Parser/DBIx/Class.pm +++ b/lib/SQL/Translator/Parser/DBIx/Class.pm @@ -45,12 +45,8 @@ sub parse { croak 'No DBIx::Class::Schema' unless ($dbicschema); if (!ref $dbicschema) { - try { - eval "require $dbicschema;" - } - catch { - croak "Can't load $dbicschema ($_)"; - } + eval "require $dbicschema" + or croak "Can't load $dbicschema: $@"; } my $schema = $tr->schema; @@ -154,7 +150,11 @@ sub parse { # Ignore any rel cond that isn't a straight hash next unless ref $rel_info->{cond} eq 'HASH'; - my $relsource = $source->related_source($rel); + my $relsource = try { $source->related_source($rel) }; + unless ($relsource) { + warn "Ignoring relationship '$rel' - related resultsource '$rel_info->{class}' is not registered with this schema\n"; + next; + }; # related sources might be excluded via a {sources} filter or might be views next unless exists $table_monikers{$relsource->source_name}; @@ -284,7 +284,7 @@ sub parse { # the hook might have already removed the table if ($schema->get_table($table) && $table =~ /^ \s* \( \s* SELECT \s+/ix) { - warn <<'EOW'; + carp <<'EOW'; Custom SQL through ->name(\'( SELECT ...') is DEPRECATED, for more details see "Arbitrary SQL through a custom ResultSource" in DBIx::Class::Manual::Cookbook diff --git a/t/99dbic_sqlt_parser.t b/t/99dbic_sqlt_parser.t index 61202b7..5d59834 100644 --- a/t/99dbic_sqlt_parser.t +++ b/t/99dbic_sqlt_parser.t @@ -135,6 +135,69 @@ lives_ok (sub { }); +{ + package DBICTest::PartialSchema; + + use base qw/DBIx::Class::Schema/; + + __PACKAGE__->load_classes( + { 'DBICTest::Schema' => [qw/ + CD + Track + Tag + Producer + CD_to_Producer + /]} + ); +} + +{ + my $partial_schema = DBICTest::PartialSchema->connect(DBICTest->_database); + + lives_ok (sub { + my $sqlt_schema = do { + + local $SIG{__WARN__} = sub { + warn @_ + unless $_[0] =~ /Ignoring relationship .+ related resultsource .+ is not registered with this schema/ + }; + + create_schema({ schema => $partial_schema }); + }; + + my @tables = $sqlt_schema->get_tables; + + is_deeply ( + [sort map { $_->name } @tables], + [qw/cd cd_to_producer producer tags track/], + 'partial dbic schema parsing ok', + ); + + # the primary key is currently unnamed in sqlt - adding below + my %constraints_for_table = ( + producer => [qw/prod_name /], + tags => [qw/tagid_cd tagid_cd_tag tags_fk_cd tags_tagid_tag tags_tagid_tag_cd /], + track => [qw/track_cd_position track_cd_title track_fk_cd /], + cd => [qw/cd_artist_title cd_fk_single_track /], + cd_to_producer => [qw/cd_to_producer_fk_cd cd_to_producer_fk_producer /], + ); + + for my $table (@tables) { + my $tablename = $table->name; + my @constraints = $table->get_constraints; + is_deeply ( + [ sort map { $_->name } @constraints ], + + # the primary key (present on all loaded tables) is currently named '' in sqlt + # subject to future changes + [ '', @{$constraints_for_table{$tablename}} ], + + "constraints of table '$tablename' ok", + ); + } + }, 'partial schema tests successful'); +} + done_testing; sub create_schema {