+# get_fk_method(TABLE, FIELD)
+# Internal subroutine for fetching the foreign key descriptor for TABLE.FIELD
+# if there is one. If not, returns undef.
+# This will initialize fk_method_cache if it hasn't happened yet. It is the
+# _only_ allowed way to access the contents of %fk_method_cache.
+
+# if we wanted to be even more efficient we'd create the fk methods in the
+# symbol table instead of relying on AUTOLOAD every time
+
+sub get_fk_method {
+ my ($table, $field) = @_;
+
+ # maybe should only load one table at a time?
+ fk_methods_init() unless exists($fk_method_cache{$table});
+
+ if ( exists($fk_method_cache{$table}) and
+ exists($fk_method_cache{$table}{$field}) ) {
+ return $fk_method_cache{$table}{$field};
+ } else {
+ return undef;
+ }
+
+}
+
+sub fk_methods_init {
+ warn "[fk_methods_init]\n" if $DEBUG;
+ foreach my $table ( dbdef->tables ) {
+ $fk_method_cache{$table} = fk_methods($table);
+ }
+}
+
+sub fk_methods {
+ my $table = shift;
+
+ my %hash = ();
+
+ # foreign keys we reference in other tables
+ foreach my $fk (dbdef->table($table)->foreign_keys) {
+
+ my $method = '';
+ if ( scalar( @{$fk->columns} ) == 1 ) {
+ if ( ! defined($fk->references)
+ || ! @{$fk->references}
+ || $fk->columns->[0] eq $fk->references->[0]
+ ) {
+ $method = $fk->table;
+ } else {
+ #some sort of hint in the table.pm or schema for methods not named
+ # after their foreign table (well, not a whole lot different than
+ # just providing a small subroutine...)
+ }
+
+ if ( $method ) {
+ $hash{$method} = { #fk_info
+ 'method' => 'qsearchs',
+ 'column' => $fk->columns->[0],
+ #'references' => $fk->references->[0],
+ };
+ }
+
+ }
+
+ }
+
+ # foreign keys referenced in other tables to us
+ # (alas. why we're cached. still, might this loop better be done once at
+ # schema load time insetad of every time we AUTOLOAD a method on a new
+ # class?)
+ if (! defined $fk_table_cache) {
+ foreach my $f_table ( dbdef->tables ) {
+ foreach my $fk (dbdef->table($f_table)->foreign_keys) {
+ push @{$fk_table_cache->{$fk->table}},[$f_table,$fk];
+ }
+ }
+ }
+ foreach my $fks (@{$fk_table_cache->{$table}}) {
+ my ($f_table,$fk) = @$fks;
+ my $method = '';
+ if ( scalar( @{$fk->columns} ) == 1 ) {
+ if ( ! defined($fk->references)
+ || ! @{$fk->references}
+ || $fk->columns->[0] eq $fk->references->[0]
+ ) {
+ $method = $f_table;
+ } else {
+ #some sort of hint in the table.pm or schema for methods not named
+ # after their foreign table (well, not a whole lot different than
+ # just providing a small subroutine...)
+ }
+
+ if ( $method ) {
+ $hash{$method} = { #fk_info
+ 'method' => 'qsearch',
+ 'column' => $fk->columns->[0], #references||column
+ #'references' => $fk->column->[0],
+ };
+ }
+
+ }
+ }
+
+ \%hash;
+}
+