From: Matt S Trout Date: Tue, 18 Aug 2009 03:14:12 +0000 (+0100) Subject: probably works for adding extra sources; doing some testing without before caring X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=803ffff298b3034e5b04a3b3a5e2e1565f8ba7f5;p=dbsrgits%2FDBIx-Class-ResultSource-MultipleTableInheritance.git probably works for adding extra sources; doing some testing without before caring --- diff --git a/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm b/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm index dcb40a1..191448c 100644 --- a/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm +++ b/lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm @@ -26,7 +26,7 @@ use namespace::autoclean; # # deploying the postgres rules through SQLT may be a pain though. -__PACKAGE__->mk_group_accessors(simple => qw(parent_source)); +__PACKAGE__->mk_group_accessors(simple => qw(parent_source additional_parents)); method new ($class: @args) { my $new = $class->next::method(@args); @@ -41,6 +41,32 @@ method new ($class: @args) { return $new; } +method add_additional_parent ($source) { + my ($our_pk, $their_pk) = map { + join('|',sort $_->primary_columns) + } ($self, $source); + + confess "Can't attach additional parent ${\$source->name} - it has different PKs ($their_pk versus our $our_pk)" + unless $their_pk eq $our_pk; + $self->additional_parents([ + @{$self->additional_parents||[]}, $source + ]); + $self->add_columns( + map { + $_ => # put the extra key first to default it + { originally_defined_in => $source->name, %{$source->column_info($_)}, }, + } grep !$self->has_column($_), $source->columns + ); + foreach my $rel ($source->relationships) { + my $rel_info = $source->relationship_info($rel); + $self->add_relationship( + $rel, $rel_info->{source}, $rel_info->{cond}, + # extra key first to default it + {originally_defined_in => $source->name, %{$rel_info->{attrs}}}, + ); + } +} + method schema (@args) { my $ret = $self->next::method(@args); if (@args) { @@ -86,17 +112,26 @@ method attach_additional_sources () { # we don't need to add the PK cols explicitly if we're the root table # since they'll get added below + my %pk_join; + if ($parent) { - my %join; foreach my $pri ($self->primary_columns) { my %info = %{$self->column_info($pri)}; delete @info{qw(is_auto_increment sequence auto_nextval)}; $table->add_column($pri => \%info); - $join{"foreign.${pri}"} = "self.${pri}"; + $pk_join{"foreign.${pri}"} = "self.${pri}"; } # have to use source name lookups rather than result class here # because we don't actually have a result class on the raw sources - $table->add_relationship('parent', $parent->raw_source_name, \%join); + $table->add_relationship('parent', $parent->raw_source_name, \%pk_join); + $self->depends_on->{$parent->source_name} = 1; + } + + foreach my $add (@{$self->additional_parents||[]}) { + $table->add_relationship( + 'parent_'.$add->name, $add->source_name, \%pk_join + ); + $self->depends_on->{$add->source_name} = 1; } # add every column that's actually a concrete part of us @@ -122,6 +157,10 @@ method attach_additional_sources () { foreach my $rel ($self->relationships) { my $rel_info = $self->relationship_info($rel); + # if we got this from the superclass, -its- raw table will nail this. + # if we got it from an additional parent, it's its problem. + next unless $rel_info->{attrs}{originally_defined_in} eq $self->name; + my $f_source = $schema->source($rel_info->{source}); # __PACKAGE__ is correct here because subclasses should be caught @@ -180,6 +219,13 @@ method add_columns (@args) { return $ret; } +method add_relationship ($name, $f_source, $cond, $attrs) { + $self->next::method( + $name, $f_source, $cond, + { originally_defined_in => $self->name, %{$attrs||{}}, } + ); +} + BEGIN { # helper routines, constructed as anon subs so autoclean nukes them