package SQL::Translator::Producer::Diagram;
# -------------------------------------------------------------------
-# $Id: Diagram.pm,v 1.9 2004-02-09 23:02:13 kycl4rk Exp $
+# $Id$
# -------------------------------------------------------------------
# Copyright (C) 2002-4 SQLFairy Authors
#
use SQL::Translator;
- my $t = SQL::Translator->new( parser => 'MySQL', '...' );
+ my $t = SQL::Translator->new( producer => 'Diagram', '...' );
$t->translate;
-Or use more directly:
-
- use SQL::Translator;
- use SQL::Translator::MySQL 'parse';
-
- my $t = SQL::Translator->new( filename => '...' );;
- parse( $t,
-
-
=cut
use strict;
use SQL::Translator::Utils qw(debug);
use vars qw[ $VERSION $DEBUG ];
-$VERSION = sprintf "%d.%02d", q$Revision: 1.9 $ =~ /(\d+)\.(\d+)/;
+$VERSION = sprintf "%d.%02d", q$Revision$ =~ /(\d+)\.(\d+)/;
$DEBUG = 0 unless defined $DEBUG;
use constant VALID_FONT_SIZE => {
my $font_size = $args->{'font_size'} || 'medium';
my $imap_file = $args->{'imap_file'} || '';
my $imap_url = $args->{'imap_url'} || '';
+ my $gutter = $args->{'gutter'} || 30; # distance b/w columns
my $no_columns = $args->{'no_columns'};
my $no_lines = $args->{'no_lines'};
my $add_color = $args->{'add_color'};
my $skip_fields = $args->{'skip_fields'};
my %skip = map { s/^\s+|\s+$//g; $_,1 } split (/,/, $skip_fields);
- $schema->make_natural_joins(
- join_pk_only => $join_pk_only,
- skip_fields => $args->{'skip_fields'},
- ) if $natural_join;
+# my @tables = $schema->get_tables;
+ my @table_names;
+ if ( $natural_join ) {
+ $schema->make_natural_joins(
+ join_pk_only => $join_pk_only,
+ skip_fields => $args->{'skip_fields'},
+ );
+
+ my $g = $schema->as_graph_pm;
+ my $d = Graph::Traversal::DFS->new( $g, next_alphabetic => 1 );
+ $d->preorder;
+
+ @table_names = $d->dfs;
+ }
+ else {
+ @table_names = map { $_->name } $schema->get_tables;
+ }
die "Invalid image type '$output_type'"
unless VALID_IMAGE_TYPE ->{ $output_type };
#
# Layout the image.
#
- my $font =
- $font_size eq 'small' ? gdTinyFont :
- $font_size eq 'medium' ? gdSmallFont :
- $font_size eq 'large' ? gdLargeFont : gdGiantFont;
- my @tables = $schema->get_tables;
- my $no_tables = scalar @tables;
+ my $font
+ = $font_size eq 'small' ? gdTinyFont
+ : $font_size eq 'medium' ? gdSmallFont
+ : $font_size eq 'large' ? gdLargeFont
+ : gdGiantFont;
+
+ my $no_tables = scalar @table_names;
$no_columns = 0 unless $no_columns =~ /^\d+$/;
$no_columns ||= sprintf( "%.0f", sqrt( $no_tables ) + .5 );
$no_columns ||= .5;
my $cur_col = 1; # the current column
my $no_this_col = 0; # number of tables in current column
my $this_col_x = $x; # current column's x
- my $gutter = 30; # distance b/w columns
my %nj_registry; # for locations of fields for natural joins
my @fk_registry; # for locations of fields for foreign keys
my %table_x; # for max x of each table
my @imap_coords; # for making clickable image map
my %legend;
- for my $table ( @tables ) {
- my $table_name = $table->name;
- my $top = $y;
+ for my $table_name ( @table_names ) {
+ my $table = $schema->get_table( $table_name );
+ my $top = $y;
push @shapes,
[ 'string', $font, $this_col_x, $y, $table_name, 'black' ];
$y += $font->height + 2;
my @fields = $table->get_fields;
debug("Fields = ", join(', ', map { $_->name } @fields));
- my ( @fld_desc, $max_name );
+ my ( @fld_desc, $max_name, $max_desc );
for my $f ( @fields ) {
my $name = $f->name or next;
my $is_pk = $f->is_primary_key;
+ my @attr;
+
#
# Decide if we should skip this field.
#
}
if ( $is_pk ) {
- $name .= ' *';
- $legend{'Primary key'} = '*';
+ push @attr, 'PK';
+ $legend{'Primary key'} = '[PK]';
}
if ( $f->is_unique ) {
- $name .= ' [U]';
+ push @attr, 'U';
$legend{'Unique constraint'} = '[U]';
}
+ if ( $f->is_foreign_key ) {
+ push @attr, 'FK';
+ $legend{'Foreign Key'} = '[FK]';
+ }
+
+ my $attr = '';
+ if ( @attr ) {
+ $attr .= '[' . join(', ', @attr) . ']';
+ }
+
my $desc = $f->data_type;
- $desc .= '('.$f->size.')' if $f->size;
+ $desc .= '('.$f->size.')' if $f->size &&
+ $f->data_type =~ /^(VAR)?CHAR2?$/i;
my $nlen = length $name;
+ my $dlen = length $desc;
$max_name = $nlen if $nlen > $max_name;
- push @fld_desc, [ $name, $desc, $f->{'name'}, $is_pk ];
+ $max_desc = $dlen if $dlen > $max_desc;
+ push @fld_desc, [ $name, $desc, $f->{'name'}, $is_pk, $attr ];
}
- $max_name += 4;
+ $max_name += 2;
+ $max_desc += 2;
for my $fld_desc ( @fld_desc ) {
- my ( $name, $desc, $orig_name, $is_pk ) = @$fld_desc;
- my $diff = $max_name - length $name;
- $name .= ' ' x $diff;
- $desc = $name . $desc;
+ my ( $name, $desc, $orig_name, $is_pk, $attr ) = @$fld_desc;
+ my $diff1 = $max_name - length $name;
+ my $diff2 = $max_desc - length $desc;
+ $name .= ' ' x $diff1;
+ $desc .= ' ' x $diff2;
+ $desc = $name . $desc . $attr;
push @shapes, [ 'string', $font, $this_col_x, $y, $desc, 'black' ];
$y += $font->height + 2;
}
}
- my $sig = __PACKAGE__." $VERSION";
+ my $sig = 'Created by SQL::Translator ' . $t->version;
my $sig_len = $font->width * length $sig;
push @shapes, [
'string', $font, $max_x - $sig_len, $max_y - $font->height - 4,