[Catalyst] Adjacency list "trees" and DBIC (recursion fun)

Dylan Vanderhoof DylanV at semaphore.com
Thu Dec 14 19:00:22 GMT 2006


Hello all,
	I have a bit of a niche question, but maybe somebody has run
into this.
My environment is Catalyst (latest stable), DBIx::Class and TT.  Below
is a table description and some chunk of code I'm actually using with
altered names.

I'm wanting to traverse the tree and just have debug statements to tell
me what node I found and what order the node is.
However, when running, it seems to recurse endlessly, which isn't
happening in my pure-perl/DBI version.  I'm guessing there's something
about DBIC I'm running into that's making this not work and there should
be a better approach.  Anybody have any suggestions?  =)

(I put this on the Cat list because I'll almost certainly follow up with
some Catalyst/TT questions, but I can punt it to the DBIC list if that
makes more sens.)

Thanks,
Dylan

---------------------------------------
Table structure and code follows

I have a self-referencing table that forms a tree using an adjacency
list, more or less of the format:


Table Foo:

id int not null pk
parent int fk referencing self.id
is_leaf boolean 
[data columns]


A null parent is a root, and any node where is_leaf is true is the end
of a branch.


My DBIC config has (among other things):

__PACKAGE__->has_many(
  "foo",
  "MyApp::Schema::Foo",
  { "foreign.parent" => "self.id" },
);


My thought was that I should be able to do:



sub someroutine : Whatever {

$rs = $schema->resultset('Foo')->search( { parent => undef } ); # root
nodes

while( $root_node = $rs->next ) {
   if( $root_node->leaf_node == 0 ) {
       $c->log->debug("Root is a left, stopping");
   } else {
       while ( $child = $root_node->foo->next ) {
           traverse_tree( $c, $root_node, $child, 2);
       }
   }
}


sub traverse_tree {
    my $c = shift;
    my $parent = shift;
    my $child = shift;
    my $order = shift;
    my $next_child;

    if( $child->leaf_node == 0 )
    {
        $c->log->debug( "Got order $order child: " . $child->description
);
        while( $next_child = $child->foo->next ) {
            build_tree( $c, $child, $next_child, $order + 1 );
        }
    } else {
        $c->log->debug( "Got order $order child (leaf): " .
$child->description );
    }
}



More information about the Catalyst mailing list