So I decided to let the database handle any circular dependencies (it will fail to define one of the tables and I have to then roll back everything) but apart from that I have a working topological sort. Thanks to all who helped out.
my $csvQ = {};
for my $csv ($obj->_globcsv) {
my $base = basename $csv;
$base =~ s/\.txt$//;
$base = lc($base);
$obj->_csv2arr($csv);
$csvQ->{$base}{table} = $obj->_getset('ar');
}
$obj->_getset('csvQ', $csvQ);
for my $table ( sort _DBsort4create keys %$csvQ ) {
$obj->_getset('ar', $csvQ->{$table}{table});
$obj->_arr2db; # process the csv into the db
}
sub _DBsort4create {
my $obj = shift;
my $csvQ = $obj->_getset('csvQ');
for my $ab ($a, $b) {
unless(exists($csvQ->{$ab}{ancestor})) {
$csvQ->{$ab}{ancestor} = {};
ROWDBS4C: for (my $row=1; $row <= $#{$csvQ->{$ab}{table}}; $ro
+w++) { # avoid first row, which is a header not csv data
($csvQ->{$ab}{table}[$row][0] eq '__COLUMNS__')
and last ROWDBS4C;
if ($csvQ->{$ab}{table}[$row][0] eq 'FK') {
$csvQ->{$ab}{ancestor}{$csvQ->{$ab}{table}[$row][2]}='
+';
}
}
}
}
if (exists($csvQ->{$a}{ancestor}{$b})) {
return 1;
}
elsif (exists($csvQ->{$b}{ancestor}{$a})) {
return -1;
}
return 0;
}
Sorts by ancestral relationship of FKs. Minor optimisation similar to orcish manoevre: only search a csv array for FK entries once.