" is an actual table in the database, treat
54
|
|
|
|
|
|
|
# this as a foreign key. |
55
|
|
|
|
|
|
|
# This is my convention; override it to suit your needs. |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
my ($self, $table, $field) = @_; |
58
|
|
|
|
|
|
|
return if $field =~ /$table[_-]id/i; |
59
|
|
|
|
|
|
|
return unless $field =~ /^(.*)[_-]id$/i; |
60
|
|
|
|
|
|
|
my $candidate = $1; |
61
|
|
|
|
|
|
|
return unless $self->is_table($candidate); |
62
|
|
|
|
|
|
|
return $candidate; |
63
|
|
|
|
|
|
|
} |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
sub graph_tables { |
66
|
|
|
|
|
|
|
my $self = shift; |
67
|
|
|
|
|
|
|
|
68
|
|
|
|
|
|
|
my %table = map { $_ => 1 } $self->get_tables; |
69
|
|
|
|
|
|
|
|
70
|
|
|
|
|
|
|
for my $table ($self->get_tables) { |
71
|
|
|
|
|
|
|
my $sth = $self->get_dbh->prepare( |
72
|
|
|
|
|
|
|
"select * from $table where 1 = 0"); |
73
|
|
|
|
|
|
|
$sth->execute; |
74
|
|
|
|
|
|
|
my @fields = @{ $sth->{NAME} }; |
75
|
|
|
|
|
|
|
$sth->finish; |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
my $label = "{$table|"; |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
for my $field (@fields) { |
80
|
|
|
|
|
|
|
$label .= $field.'\l'; |
81
|
|
|
|
|
|
|
if (my $dep = $self->is_foreign_key($table, $field)) { |
82
|
|
|
|
|
|
|
$self->{g}->add_edge({ from => $table, to => $dep }); |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
$self->{g}->add_node({ name => $table, |
86
|
|
|
|
|
|
|
shape => 'record', |
87
|
|
|
|
|
|
|
label => "$label}", |
88
|
|
|
|
|
|
|
}); |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
} |
91
|
|
|
|
|
|
|
return $self->{g}; |
92
|
|
|
|
|
|
|
} |
93
|
|
|
|
|
|
|
|
94
|
|
|
|
|
|
|
sub AUTOLOAD { |
95
|
|
|
|
|
|
|
my $self = shift; |
96
|
|
|
|
|
|
|
my $type = ref($self) or croak "$self is not an object"; |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
(my $name = $AUTOLOAD) =~ s/.*:://; |
99
|
|
|
|
|
|
|
return if $name =~ /DESTROY/; |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
# hm, maybe GraphViz knows what to do with it... |
102
|
|
|
|
|
|
|
$self->{g}->$name(@_); |
103
|
|
|
|
|
|
|
} |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
1; |
106
|
|
|
|
|
|
|
__END__ |