Category: Databases
Author/Contact Info
Description: If you have a large and poorly-documented database with foreign keys defining relations between tables, this performs a breadth-first search to get from one named table to another. It makes use of the DBIx::SystemCatalog module.
use DBI;
use DBIx::SystemCatalog;
use strict;

my $dbh = DBI->connect("dbi:Oracle:DATABASENAME", "USERNAME", "PASSWOR
+D", {
        AutoCommit => 0
});

my $catalog = new DBIx::SystemCatalog $dbh;
$catalog->schema('SCHEMANAME');

my %successor;
for ($catalog->relationships()){
# this list took a long time to generate.
    push @{$successor{ $_->{from_table} }} , $_->{to_table} ;
    push @{$successor{ $_->{to_table} }} , $_->{from_table} ; 
}

#start the search

my $START = 'NAME_OF_START_TABLE';
my $END = 'NAME_OF_END_TABLE';

my @stack; push @stack, $START;
my $current; my %visited; my %parentof;

while ($current ne $END){
    $current = pop(@stack) or die "Ran out of things to search";
    $visited{$current}++;
    print "Currently searching: $current\n";

    for (@{$successor{$current}}){
        next if /DICT$/; # Ignore table names ending in "DICT" - it he
+lped in my case.
        next if $visited{$_};
        unshift @stack, $_;
        $parentof{$_} = $current;
        print "Queued: $current -> $_\n";     }
}

print br();
#traceback path;
my @lineage;
while ($current){
    unshift @lineage, $current;
    $current = $parentof{$current}
}

print "\nFinal path is: ", join('->', @lineage), "\n";