first cut at additional source code
Matt S Trout [Wed, 3 Jun 2009 18:09:25 +0000 (19:09 +0100)]
lib/DBIx/Class/ResultSource/MultipleTableInheritance.pm

index af0f4a4..cb9edce 100644 (file)
@@ -3,9 +3,10 @@ package DBIx::Class::ResultSource::MultipleTableInheritance;
 use strict;
 use warnings;
 use parent qw(DBIx::Class::ResultSource::View);
-use namespace::autoclean;
 use Method::Signatures::Simple;
 use Carp::Clan qw/^DBIx::Class/;
+use aliased 'DBIx::Class::ResultSource::Table';
+use namespace::autoclean;
 
 # how this works:
 #
@@ -38,6 +39,48 @@ method new ($class: @args) {
 
 method _attach_additional_sources () {
   my $raw_name = $self->_raw_source_name;
+  my $schema = $self->schema;
+
+  # if the raw source is already present we can assume we're done
+  return if grep { $_ eq $raw_name } $schema->sources;
+  # our parent should've been registered already actually due to DBIC
+  # attaching subclass sources later in load_namespaces
+  my $parent;
+  if ($self->parent_source) {
+      my $parent_name = $self->parent_source->name;
+    ($parent) = 
+      grep { $_->name eq $parent_name }
+        map $schema->source($_), $schema->sources;
+    confess "Couldn't find attached source for parent $parent_name - did you use load_classes? This module is only compatible with load_namespaces"
+      unless $parent;
+  }
+  my $table = Table->new({ name => '_'.$self->name });
+  $table->add_columns(
+    map { ($_ => { %{$self->column_info($_)} }) }
+      grep { $self->column_info($_)->{originally_defined_in} eq $self->name }
+        $self->columns
+  );
+  # we don't need to add the PK cols explicitly if we're the root table
+  # since they already got added above
+  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)};
+      $self->add_column($pri => \%info);
+      $join{"foreign.${pri}"} = "self.${pri}";
+    }
+    $self->add_relationship('parent', $parent->source_name, \%join);
+  }
+  $table->set_primary_key($self->primary_columns);
+  $schema->register_source($raw_name => $table);
+}
+
+method set_primary_key (@args) {
+  if ($self->parent_source) {
+    confess "Can't set primary key on a subclass";
+  }
+  return $self->next::method(@args);
 }
 
 method _raw_source_name () {