Integrate Dave Cash's changes.
[dbsrgits/SQL-Translator.git] / bin / sqlt-graph
1 #!/usr/bin/perl
2
3 # -------------------------------------------------------------------
4 # $Id: sqlt-graph,v 1.4 2004-02-20 02:41:47 dlc Exp $
5 # -------------------------------------------------------------------
6 # Copyright (C) 2002-4 SQLFairy Authors
7 #
8 # This program is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU General Public License as
10 # published by the Free Software Foundation; version 2.
11 #
12 # This program is distributed in the hope that it will be useful, but
13 # WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 # 02111-1307  USA
21 # -------------------------------------------------------------------
22
23 =head1 NAME 
24
25 sqlt-graph - Automatically create a graph from a database schema
26
27 =head1 SYNOPSIS
28
29   ./sqlt-graph -d|--db|-f|--from=db_parser [options] schema.sql
30
31   Options:
32
33     -l|--layout        Layout schema for GraphViz
34                        ("dot," "neato," "twopi"; default "dot")
35     -n|--node-shape    Shape of the nodes ("record," "plaintext," 
36                        "ellipse," "circle," "egg," "triangle," "box," 
37                        "diamond," "trapezium," "parallelogram," "house," 
38                        "hexagon," "octagon," default "record")
39     -o|--output        Output file name (default STDOUT)
40     -t|--output-type   Output file type ("canon", "text," "ps," "hpgl,"
41                        "pcl," "mif," "pic," "gd," "gd2," "gif," "jpeg,"
42                        "png," "wbmp," "cmap," "ismap," "imap," "vrml,"
43                        "vtx," "mp," "fig," "svg," "plain," default "png")
44     -c|--color         Add colors
45     --no-fields        Don't show field names
46     --height           Image height (in inches, default "11",
47                        set to "0" to undefine)
48     --width            Image width (in inches, default "8.5", 
49                        set to "0" to undefine)
50     --natural-join     Perform natural joins
51     --natural-join-pk  Perform natural joins from primary keys only
52     --show_datatypes   Show datatype of each field
53     --show_col_sizes   Show column sizes for VARCHAR and CHAR fields
54     --show_constraints Show list of constraints for each field
55     --show-datatypes   Show datatype of each field
56     --show-sizes       Show field sizes for VARCHAR and CHAR fields
57     --show-constraints Show list of constraints for each field
58     -s|--skip          Fields to skip in natural joins
59     --debug            Print debugging information
60
61 =head1 DESCRIPTION
62
63 This script will create a graph of your schema.  Only the database
64 driver argument (for SQL::Translator) is required.  If no output file
65 name is given, then image will be printed to STDOUT, so you should
66 redirect the output into a file.
67
68 The default action is to assume the presence of foreign key
69 relationships defined via "REFERNCES" or "FOREIGN KEY" constraints on
70 the tables.  If you are parsing the schema of a file that does not
71 have these, you will find the natural join options helpful.  With
72 natural joins, like-named fields will be considered foreign keys.
73 This can prove too permissive, however, as you probably don't want a
74 field called "name" to be considered a foreign key, so you could
75 include it in the "skip" option, and all fields called "name" will be
76 excluded from natural joins.  A more efficient method, however, might
77 be to simply deduce the foriegn keys from primary keys to other fields
78 named the same in other tables.  Use the "natural-join-pk" option
79 to acheive this.
80
81 If the schema defines foreign keys, then the graph produced will be
82 directed showing the direction of the relationship.  If the foreign
83 keys are intuited via natural joins, the graph will be undirected.
84
85 =cut
86
87 # -------------------------------------------------------------------
88
89 use strict;
90 use Data::Dumper;
91 use Getopt::Long;
92 use GraphViz;
93 use Pod::Usage;
94 use SQL::Translator;
95
96 use vars '$VERSION';
97 $VERSION = sprintf "%d.%02d", q$Revision: 1.4 $ =~ /(\d+)\.(\d+)/;
98
99 #
100 # Get arguments.
101 #
102 my ( 
103     $layout, $node_shape, $out_file, $output_type, $db_driver, $add_color, 
104     $natural_join, $join_pk_only, $skip_fields, $show_datatypes,
105     $show_col_sizes, $show_constraints, $debug, $help, $height, $width,
106     $no_fields
107 );
108
109 GetOptions(
110     'd|db|f|from=s'    => \$db_driver,
111     'o|output:s'       => \$out_file,
112     'l|layout:s'       => \$layout,
113     'n|node-shape:s'   => \$node_shape,
114     't|output-type:s'  => \$output_type,
115     'height:f'         => \$height,
116     'width:f'          => \$width,
117     'c|color'          => \$add_color,
118     'no-fields'        => \$no_fields,
119     'natural-join'     => \$natural_join,
120     'natural-join-pk'  => \$join_pk_only,
121     's|skip:s'         => \$skip_fields,
122     'show-datatypes'   => $show_datatypes,
123     'show-sizes'       => $show_sizes,
124     'show-constraints' => $show_constraints,
125     'debug'            => \$debug,
126     'h|help'           => \$help,
127 ) or die pod2usage;
128 my @files = @ARGV; # the create script(s) for the original db
129
130 pod2usage(1) if $help;
131 pod2usage( -message => "No db driver specified" ) unless $db_driver;
132 pod2usage( -message => 'No input file'          ) unless @files;
133
134 my $translator           =  SQL::Translator->new( 
135     from                 => $db_driver,
136     to                   => 'GraphViz',
137     debug                => $debug || 0,
138     producer_args        => {
139         out_file         => $out_file,
140         layout           => $layout,
141         node_shape       => $node_shape,
142         output_type      => $output_type,
143         add_color        => $add_color,
144         natural_join     => $natural_join,
145         natural_join_pk  => $join_pk_only,
146         skip_fields      => $skip_fields,
147         show_datatypes   => $show_datatypes,
148         show_sizes       => $show_sizes,
149         show_constraints => $show_constraints,
150         height           => $height || 0,
151         width            => $width  || 0,
152         show_fields      => $no_fields ? 0 : 1,
153     },
154 ) or die SQL::Translator->error;
155
156 for my $file (@files) {
157     my $output = $translator->translate( $file ) or die
158                  "Error: " . $translator->error;
159     if ( $out_file ) {
160         print "Image written to '$out_file'.  Done.\n";
161     }
162     else {
163         print $output;
164     }
165 }
166
167 # -------------------------------------------------------------------
168
169 =pod
170
171 =head1 AUTHOR
172
173 Ken Y. Clark E<lt>kclark@cpan.orgE<gt>.
174
175 =head1 SEE ALSO
176
177 perl, SQL::Translator.
178
179 =cut