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