Add pseudo-DAG support to adjacency lists.
Aran Deltac [Sat, 8 Apr 2006 14:32:59 +0000 (14:32 +0000)]
lib/DBIx/Class/Tree.pm
lib/DBIx/Class/Tree/AdjacencyList.pm
lib/DBIx/Class/Tree/AdjacencyList/Ordered.pm
t/lib/TreeTest.pm

index cb345b2..86bc7ce 100644 (file)
@@ -1,5 +1,5 @@
-# vim: ts=8:sw=4:sts=4:et
 package DBIx::Class::Tree;
+# vim: ts=8:sw=4:sts=4:et
 
 use strict;
 use warnings;
index 457602c..4c9a758 100644 (file)
@@ -1,7 +1,9 @@
-# vim: ts=8:sw=4:sts=4:et
 package DBIx::Class::Tree::AdjacencyList;
+# vim: ts=8:sw=4:sts=4:et
+
 use strict;
 use warnings;
+
 use base qw( DBIx::Class );
 use Carp qw( croak );
 
@@ -64,6 +66,10 @@ ID which defines the parent row.  Defaults to "parent_id".  This
 will create a has_many (children) and belongs_to (parent) 
 relationship.
 
+This method also setups an additional has_many relationship called 
+parents which is useful when you want to treat an adjacency list 
+as a DAG.
+
 =cut
 
 __PACKAGE__->mk_classdata( '_parent_column' => 'parent_id' );
@@ -75,6 +81,7 @@ sub parent_column {
         my $primary_col = ($class->primary_columns())[0];
         $class->belongs_to( '_parent' => $class => { "foreign.$primary_col" => "self.$parent_col" } );
         $class->has_many( 'children' => $class => { "foreign.$parent_col" => "self.$primary_col" } );
+        $class->has_many( 'parents' => $class => { "foreign.$primary_col" => "self.$parent_col" } );
         $class->_parent_column( $parent_col );
         return 1;
     }
@@ -113,6 +120,17 @@ sub parent {
     return $self->_parent();
 }
 
+=head2 parents
+
+  my $parents = $node->parents();
+  my @parents = $node->parents();
+
+This has_many relationship is not that useful as it will 
+never return more than one parent due to the one-to-many 
+structure of adjacency lists.  The reason this relationship 
+is defined is so that this tree type may be treated as if 
+it was a DAG.
+
 =head2 children
 
   my $children_rs = $employee->children();
index 1481c0a..d3b7eb2 100644 (file)
@@ -1,7 +1,9 @@
-# vim: ts=8:sw=4:sts=4:et
 package DBIx::Class::Tree::AdjacencyList::Ordered;
+# vim: ts=8:sw=4:sts=4:et
+
 use strict;
 use warnings;
+
 use base qw( DBIx::Class );
 use Carp qw( croak );
 
index 137ea17..e77eea1 100644 (file)
@@ -8,7 +8,7 @@ use TreeTest::Schema;
 our $NODE_COUNT = 80;
 
 sub count_tests {
-    my $count = 11;
+    my $count = 13;
     if( TreeTest::Schema::Node->can('position_column') ){
         $count ++;
     }
@@ -46,6 +46,9 @@ sub run_tests {
     ok( ($nodes->find(22)->children->count()==2), 'node 22 has correct number of children' );
     ok( ($nodes->find(22)->siblings->count()==3), 'node 22 has correct number of siblings' );
 
+    ok( ($nodes->find(22)->parents->count()==1), 'node 22 has correct number of parents' );
+    ok( (($nodes->find(22)->parents->all())[0]->id()==$nodes->find(22)->parent->id()), 'node 22 parent matches parents' );
+
     if( TreeTest::Schema::Node->can('position_column') ){
         ok( check_positions(scalar $root->children()), 'positions are correct' );
     }