Skip Menu |

This queue is for tickets about the SQL-Translator CPAN distribution.

Report information
The Basics
Id: 24278
Status: new
Priority: 0/
Queue: SQL-Translator

People
Owner: Nobody in particular
Requestors: T.J.Adye [...] rl.ac.uk
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: 0.08_04
Fixed in: (no value)



Subject: patch - add sqlt-graph/GraphViz global and item-specific display options
Add GraphViz options to the sqlt-graph command (-g) and the SQL::Translator::Producer::GraphViz module (graphviz_options). This accepts all GraphViz display options, not just those that the producer knows about. These can be applied globally, or to individual tables, joins, or constraints (selected by name or regular expression). See the SQL::Translator::Producer::GraphViz POD for details. Change sqlt-graph --width and --height defaults to 8.5x11, to agree with help text (defaults were 0). Also, for completeness, allow 'circo' and 'fdp' layouts and 'debug' output type. Small fixes to the sqlt-graph help. (Linux 2.4.21-47.EL, perl 5.8.0, SQL-Translator-0.08_04)
Subject: SQL-Translator-0.08-2.patch
diff -ur SQL-Translator-0.08-orig/bin/sqlt-graph SQL-Translator-0.08/bin/sqlt-graph --- SQL-Translator-0.08-orig/bin/sqlt-graph 2006-12-07 14:05:17.000000000 +0000 +++ SQL-Translator-0.08/bin/sqlt-graph 2007-01-08 19:13:31.000000000 +0000 @@ -31,16 +31,18 @@ Options: -l|--layout Layout schema for GraphViz - ("dot," "neato," "twopi"; default "dot") - -n|--node-shape Shape of the nodes ("record," "plaintext," - "ellipse," "circle," "egg," "triangle," "box," - "diamond," "trapezium," "parallelogram," "house," - "hexagon," "octagon," default "record") + ("dot," "neato," "twopi", "circo", "fdp"; + default "dot") + -n|--node-shape Shape of the nodes ("record", "plaintext", + "ellipse", "circle", "egg", "triangle", "box", + "diamond", "trapezium", "parallelogram", "house", + "hexagon", "octagon", default "record") -o|--output Output file name (default STDOUT) - -t|--output-type Output file type ("canon", "text," "ps," "hpgl," - "pcl," "mif," "pic," "gd," "gd2," "gif," "jpeg," - "png," "wbmp," "cmap," "ismap," "imap," "vrml," - "vtx," "mp," "fig," "svg," "plain," default "png") + -t|--output-type Output file type ("canon", "text", "ps", "hpgl", + "pcl", "mif", "pic", "gd", "gd2", "gif", "jpeg", + "png", "wbmp", "cmap", "ismap", "imap", "vrml", + "vtx", "mp", "fig", "svg", "plain", "debug", + default "png") -c|--color Add colors --no-fields Don't show field names --height Image height (in inches, default "11", @@ -53,6 +55,10 @@ --show-sizes Show column sizes for VARCHAR and CHAR fields --show-constraints Show list of constraints for each field -s|--skip Fields to skip in natural joins + -g|--graphviz-options Detailed GraphViz options, separated with commas + or separate -g options. eg. + -g directed=0,edge=color=blue + --debug Print debugging information =head1 DESCRIPTION @@ -100,7 +106,7 @@ $layout, $node_shape, $out_file, $output_type, $db_driver, $add_color, $natural_join, $join_pk_only, $skip_fields, $show_datatypes, $show_sizes, $show_constraints, $debug, $help, $height, $width, - $no_fields + $no_fields, @graphviz_options ); GetOptions( @@ -119,6 +125,7 @@ 'show-datatypes' => \$show_datatypes, 'show-sizes' => \$show_sizes, 'show-constraints' => \$show_constraints, + 'g|graphviz-options:s'=> \@graphviz_options, 'debug' => \$debug, 'h|help' => \$help, ) or die pod2usage; @@ -144,9 +151,10 @@ show_datatypes => $show_datatypes, show_sizes => $show_sizes, show_constraints => $show_constraints, - height => $height || 0, - width => $width || 0, + height => $height, + width => $width, show_fields => $no_fields ? 0 : 1, + graphviz_options => [map split(/,/), @graphviz_options], }, ) or die SQL::Translator->error; diff -ur SQL-Translator-0.08-orig/lib/SQL/Translator/Producer/GraphViz.pm SQL-Translator-0.08/lib/SQL/Translator/Producer/GraphViz.pm --- SQL-Translator-0.08-orig/lib/SQL/Translator/Producer/GraphViz.pm 2006-12-07 14:05:17.000000000 +0000 +++ SQL-Translator-0.08/lib/SQL/Translator/Producer/GraphViz.pm 2007-01-08 19:10:17.000000000 +0000 @@ -62,8 +62,10 @@ determines which layout algorithm GraphViz will use; possible values are 'dot' (the default GraphViz layout for directed graph -layouts), 'neato' (for undirected graph layouts - spring model) -or 'twopi' (for undirected graph layouts - circular) +layouts), 'neato' (for undirected graph layouts - spring model), +'twopi' (for undirected graph layouts - circular), +'circo' (for undirected graph layouts - circular), or 'fdp' +(for undirected graph layouts - force directed spring model) =item * node_shape (DEFAULT: 'record') @@ -77,7 +79,7 @@ sets the file type of the output graphic; possible values are 'ps', 'hpgl', 'pcl', 'mif', 'pic', 'gd', 'gd2', 'gif', 'jpeg', 'png', 'wbmp', 'cmap', 'ismap', 'imap', 'vrml', 'vtx', 'mp', -'fig', 'svg', 'canon', 'plain' or 'text' (see GraphViz for +'fig', 'svg', 'canon', 'plain', 'text', or 'debug' (see GraphViz for details on each of these) =item * width (DEFAULT: 8.5) @@ -146,6 +148,54 @@ natural_join above) of SQL::Translator::Schema, if either the natural_join or join_pk_only options has a true value +=item * graphviz_options + +additional GraphViz formatting options array reference. +Each option can be of the form:- + +=over 4 + +=item OPTION=VALUE + +set option globally + +=item node=OPTION=VALUE + +=item edge=OPTION=VALUE + +=item graph=OPTION=VALUE + +set node, edge, or graph option + +=item table=TABLE=OPTION=VALUE + +=item join=TABLE1-TABLE2=OPTION=VALUE + +=item constraint=CONSTRAINT=OPTION=VALUE + +set option for a particular table, join, or constraint. +TABLE specifies the table name, TABLE1-TABLE2 specifies a join +(can be in either order), and CONSTRAINT specifies a constraint name +(all ignoring case). +Can also be given as (anchored) regular expressions to select +multiple items. + +=back + +In all cases, =VALUE can be ommitted to set the option to 1. +See the GraphViz module documentation for a full list of options. + +example: + + producer_args => { + ... + graphviz_options => [qw( + directed=0 + edge=color=blue + table=priority_table=style=bold + join=priority_table-.*=color=red + )]} + =back =cut @@ -164,6 +214,8 @@ dot => 1, neato => 1, twopi => 1, + circo => 1, + fdp => 1, }; use constant VALID_NODE_SHAPE => { @@ -183,6 +235,7 @@ }; use constant VALID_OUTPUT => { + debug => 1, canon => 1, text => 1, ps => 1, @@ -235,6 +288,26 @@ split ( /,/, $skip_fields ); $natural_join ||= $join_pk_only; + my %graphviz_options; + my %element_options= (node => {}, edge => {}, graph => {}); + my %schema_options= (table => [], join => [], constraint => []); + foreach (@{$args->{'graphviz_options'}}) { + my ($key, $val); + ($key, $val)= /^([^=]*)=(.*)$/ or ($key, $val)= ($_, 1); + if ($schema_options{$key} && (my ($sel, $rest)= ($val =~ /^([^=]*)=(.*)$/))) { + $sel= qr/^$sel$/i; + my ($xkey, $xval); + ($xkey, $xval)= ($rest =~ /^([^=]*)=(.*)$/) or ($xkey, $xval)= ($rest, 1); + push (@{$schema_options{$key}}, {sel => $sel, key => $xkey, val => $xval}); + } elsif ($element_options{$key}) { + my ($xkey, $xval); + ($xkey, $xval)= ($val =~ /^([^=]*)=(.*)$/) or ($xkey, $xval)= ($val, 1); + $element_options{$key}{$xkey}= $xval; + } else { + $graphviz_options{$key}= $val; + } + } + $schema->make_natural_joins( join_pk_only => $join_pk_only, skip_fields => $args->{'skip_fields'}, @@ -262,9 +335,13 @@ node => { shape => $node_shape, style => 'filled', - fillcolor => 'white' - } + fillcolor => 'white', + %{$element_options{'node'}} + }, + %graphviz_options, ); + $args{'edge'} = $element_options{'edge'} if %{$element_options{'edge'}}; + $args{'graph'} = $element_options{'graph'} if %{$element_options{'graph'}}; $args{'width'} = $width if $width; $args{'height'} = $height if $height; @@ -301,7 +378,14 @@ } @fields ) . '\l'; my $label = $show_fields ? "{$table_name|$field_str}" : $table_name; - $gv->add_node( $table_name, label => $label ); + + my %opt; + if ($schema_options{'table'}) { + for my $table (@{$schema_options{'table'}}) { + $table_name =~ /$table->{'sel'}/ and $opt{$table->{'key'}}= $table->{'val'}; + } + } + $gv->add_node( $table_name, label => $label, %opt ); debug("Processing table '$table_name'"); @@ -330,11 +414,17 @@ for my $c ( $table->get_constraints ) { next unless $c->type eq FOREIGN_KEY; my $fk_table = $c->reference_table or next; + my %opt; + if ($schema_options{'constraint'}) { + for my $constraint (@{$schema_options{'constraint'}}) { + $c->name =~ /$constraint->{'sel'}/ and $opt{$constraint->{'key'}}= $constraint->{'val'}; + } + } for my $field_name ( $c->fields ) { for my $fk_field ( $c->reference_fields ) { next unless defined $schema->get_table( $fk_table ); - push @fk_registry, [ $table_name, $fk_table ]; + push @fk_registry, [ $table_name, $fk_table, (%opt ? (\%opt) : ())]; } } } @@ -358,7 +448,9 @@ my %done; for my $bunch ( @table_bunches ) { - my @tables = @$bunch; + my @tables = @{$bunch}; + my $opt; + $opt= pop @tables if ref $tables[-1]; for my $i ( 0 .. $#tables ) { my $table1 = $tables[ $i ]; @@ -366,7 +458,16 @@ my $table2 = $tables[ $j ]; next if $table1 eq $table2; next if $done{ $table1 }{ $table2 }; - $gv->add_edge( $table2, $table1 ); + my %jopt; + %jopt= %$opt if $opt; + if ($schema_options{'join'}) { + for my $join (@{$schema_options{'join'}}) { + if (("$table1-$table2" =~ /$join->{'sel'}/) || ("$table2-$table1" =~ /$join->{'sel'}/)) { + $jopt{$join->{'key'}}= $join->{'val'}; + } + } + } + $gv->add_edge( $table2, $table1, %jopt ); $done{ $table1 }{ $table2 } = 1; $done{ $table2 }{ $table1 } = 1; }