Catch case of specifying 'DBI-Driver' and quietly fix this.
[dbsrgits/SQL-Translator.git] / script / sqlt-graph
CommitLineData
d5132e19 1#!/usr/bin/env perl
354b1807 2
3# -------------------------------------------------------------------
478f608d 4# Copyright (C) 2002-2009 SQLFairy Authors
354b1807 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
23sqlt-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
d5132e19 43 --cluster Cluster tables
354b1807 44 --no-fields Don't show field names
45 --height Image height (in inches, default "11",
46 set to "0" to undefine)
47 --width Image width (in inches, default "8.5",
48 set to "0" to undefine)
027cebc7 49 --fontsize custom font size for node and edge labels
50 --fontname name of custom font (or full path to font file) for
51 node, edge, and graph labels
52 --nodeattr attribute name and value (in key=val syntax) for
53 nodes; this option may be repeated to specify
54 multiple node attributes
55 --edgeattr same as --nodeattr, but for edge attributes
56 --graphattr same as --nodeattr, but for graph attributes
354b1807 57 --natural-join Perform natural joins
58 --natural-join-pk Perform natural joins from primary keys only
88c73648 59 --show-datatypes Show datatype of each field
60 --show-sizes Show column sizes for VARCHAR and CHAR fields
7b908fb7 61 --show-constraints Show list of constraints for each field
354b1807 62 -s|--skip Fields to skip in natural joins
818e0d98 63 --skip-tables Comma-separated list of table names to exclude
64 --skip-tables-like Comma-separated list of regexen to exclude tables
354b1807 65 --debug Print debugging information
66
67=head1 DESCRIPTION
68
69This script will create a graph of your schema. Only the database
70driver argument (for SQL::Translator) is required. If no output file
71name is given, then image will be printed to STDOUT, so you should
72redirect the output into a file.
73
74The default action is to assume the presence of foreign key
75relationships defined via "REFERNCES" or "FOREIGN KEY" constraints on
76the tables. If you are parsing the schema of a file that does not
77have these, you will find the natural join options helpful. With
78natural joins, like-named fields will be considered foreign keys.
79This can prove too permissive, however, as you probably don't want a
80field called "name" to be considered a foreign key, so you could
81include it in the "skip" option, and all fields called "name" will be
82excluded from natural joins. A more efficient method, however, might
83be to simply deduce the foriegn keys from primary keys to other fields
84named the same in other tables. Use the "natural-join-pk" option
85to acheive this.
86
87If the schema defines foreign keys, then the graph produced will be
88directed showing the direction of the relationship. If the foreign
89keys are intuited via natural joins, the graph will be undirected.
90
d5132e19 91The syntax for clustering tables into groups is:
92
93 cluster1=table1,table2;cluster2=table3,table4
94
354b1807 95=cut
96
97# -------------------------------------------------------------------
98
99use strict;
d5132e19 100use warnings;
354b1807 101use Data::Dumper;
102use Getopt::Long;
103use GraphViz;
104use Pod::Usage;
105use SQL::Translator;
106
da06ac74 107use vars '$VERSION';
4ab3763d 108$VERSION = '1.59';
da06ac74 109
354b1807 110#
111# Get arguments.
112#
113my (
114 $layout, $node_shape, $out_file, $output_type, $db_driver, $add_color,
d491c962 115 $natural_join, $join_pk_only, $skip_fields, $show_datatypes,
f382d57f 116 $show_sizes, $show_constraints, $debug, $help, $height, $width,
d5132e19 117 $no_fields, $fontsize, $fontname, $skip_tables, $skip_tables_like,
118 $cluster
354b1807 119);
120
027cebc7 121# multi-valued options:
122my %edgeattrs = ();
123my %nodeattrs = ();
124my %graphattrs = ();
125
354b1807 126GetOptions(
26b2ec84 127 'd|db|f|from=s' => \$db_driver,
818e0d98 128 'o|output:s' => \$out_file,
129 'l|layout:s' => \$layout,
130 'n|node-shape:s' => \$node_shape,
131 't|output-type:s' => \$output_type,
132 'height:f' => \$height,
133 'width:f' => \$width,
26b2ec84 134 'fontsize=i' => \$fontsize,
135 'fontname=s' => \$fontname,
136 'nodeattr=s' => \%nodeattrs,
137 'edgeattr=s' => \%edgeattrs,
138 'graphattr=s' => \%graphattrs,
818e0d98 139 'c|color' => \$add_color,
d5132e19 140 'cluster:s' => \$cluster,
818e0d98 141 'no-fields' => \$no_fields,
142 'natural-join' => \$natural_join,
143 'natural-join-pk' => \$join_pk_only,
144 's|skip:s' => \$skip_fields,
145 'skip-tables:s' => \$skip_tables,
146 'skip-tables-like:s' => \$skip_tables_like,
147 'show-datatypes' => \$show_datatypes,
148 'show-sizes' => \$show_sizes,
149 'show-constraints' => \$show_constraints,
150 'debug' => \$debug,
151 'h|help' => \$help,
354b1807 152) or die pod2usage;
153my @files = @ARGV; # the create script(s) for the original db
154
155pod2usage(1) if $help;
156pod2usage( -message => "No db driver specified" ) unless $db_driver;
157pod2usage( -message => 'No input file' ) unless @files;
158
7b908fb7 159my $translator = SQL::Translator->new(
160 from => $db_driver,
161 to => 'GraphViz',
162 debug => $debug || 0,
163 producer_args => {
164 out_file => $out_file,
165 layout => $layout,
166 node_shape => $node_shape,
167 output_type => $output_type,
168 add_color => $add_color,
169 natural_join => $natural_join,
170 natural_join_pk => $join_pk_only,
171 skip_fields => $skip_fields,
fddd7578 172 skip_tables => $skip_tables,
818e0d98 173 skip_tables_like => $skip_tables_like,
7b908fb7 174 show_datatypes => $show_datatypes,
175 show_sizes => $show_sizes,
176 show_constraints => $show_constraints,
d5132e19 177 cluster => $cluster,
7b908fb7 178 height => $height || 0,
179 width => $width || 0,
027cebc7 180 fontsize => $fontsize,
181 fontname => $fontname,
182 nodeattrs => \%nodeattrs,
183 edgeattrs => \%edgeattrs,
184 graphattrs => \%graphattrs,
7b908fb7 185 show_fields => $no_fields ? 0 : 1,
354b1807 186 },
187) or die SQL::Translator->error;
188
189for my $file (@files) {
190 my $output = $translator->translate( $file ) or die
191 "Error: " . $translator->error;
192 if ( $out_file ) {
193 print "Image written to '$out_file'. Done.\n";
194 }
195 else {
196 print $output;
197 }
198}
199
200# -------------------------------------------------------------------
201
202=pod
203
204=head1 AUTHOR
205
d5132e19 206Ken Youens-Clark E<lt>kclark@cpan.orgE<gt>.
354b1807 207
208=head1 SEE ALSO
209
210perl, SQL::Translator.
211
212=cut