On Thu, 14 Dec 2006, Dylan Vanderhoof wrote:

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);
      }
  }
}

What's happening here is that everytime you call ->foo->next, it's creating your a NEW resultset, and next returns the first item in it, always. DBIx::Class doesnt keep track of the resultsets it creates for you, you need to do that yourself (i.r. assign ->foo to a variable, and call next on that). This is basically to lessen the problem of references hanging around in DBIC and not getting garbage collected properly.


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 );
   }
}

_______________________________________________
List: [email protected]
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/[email protected]/
Dev site: http://dev.catalyst.perl.org/



Jess

_______________________________________________
List: [email protected]
Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst
Searchable archive: http://www.mail-archive.com/[email protected]/
Dev site: http://dev.catalyst.perl.org/

Reply via email to