CREATE TABLE node (node_id, ); CREATE TABLE edge (edge_id, from_node_id, to_node_id, ); #### sub _edges { my (%args) = @_; my $node_id = $args{node_id}; my $limit = $args{limit} || 1; my $edges = $args{edges} || []; my $iter = $args{iter} || 1; my $seen = $args{seen} || []; if ($iter > $limit) { return $edges; } my $sth = $dbh->prepare(qq{ SELECT e.edge_id, e.to_node_id AS node_id FROM edge e JOIN node n ON e.to_node_id = n.node_id WHERE e.from_node_id = ? UNION SELECT e.edge_id, e.from_node_id AS node_id FROM edge e JOIN node n ON e.from_node_id = n.node_id WHERE e.to_node_id = ? }); $sth->execute($node_id, $node_id); my $res = $sth->fetchall_arrayref({}); push(@$edges, @$res); foreach my $e (@$res) { unless (_seen($seen, [$node_id, $e->{node_id}])) { push @$seen, [$node_id, $e->{node_id}]; _edges( dbh => $dbh, node_id => $e->{node_id}, node_name => $e->{node_name}, limit => $limit, abbreviate => $abbreviate, iter => $iter, edges => $edges, seen => $seen ); } } $iter++; return $edges; } sub _seen { my ($i, $j) = @_; for (@$i) { return 1 if ( (($_->[0] == $j->[0]) && ($_->[1] == $j->[1])) || (($_->[0] == $j->[1]) && ($_->[1] == $j->[0])) ); } return 0; }