- Updated GraphViz producer module per the modifications discussed on the sqlfairy...
Jonathan Yu [Fri, 9 Jan 2009 04:16:38 +0000 (04:16 +0000)]
- Cleaned up map{} code
- Added show_indexes and friendly_ints options.

TODO: the revision still needs to be updated. I'm using SVN, so it will have to be updated manually.

lib/SQL/Translator/Producer/GraphViz.pm

index 5ace4f2..f72f5e1 100644 (file)
@@ -171,6 +171,21 @@ like-named argument in the make_natural_join method (see
 natural_join above) of SQL::Translator::Schema, if either
 the natural_join or join_pk_only options has a true value
 
+=item * show_indexes
+
+if set to a true value, each record will also show the indexes
+set on each table. it describes the index types along with
+which columns are included in the index. this option requires
+that show_fields is a true value as well
+
+=item * friendly_ints
+
+if set to a true value, each integer type field will be displayed
+as a tinyint, smallint, integer or bigint depending on the field's
+associated size parameter. this only applies for the 'integer'
+type (and not the lowercase 'int' type, which is assumed to be a
+32-bit integer).
+
 =back
 
 =cut
@@ -258,6 +273,8 @@ sub produce {
     my $show_fk_only     = $args->{'show_fk_only'};
     my $show_datatypes   = $args->{'show_datatypes'};
     my $show_sizes       = $args->{'show_sizes'};
+    my $show_indexes     = $args->{'show_indexes'};
+    my $friendly_ints    = $args->{'friendly_ints'};
     my $show_constraints = $args->{'show_constraints'};
     my $join_pk_only     = $args->{'join_pk_only'};
     my $skip_fields      = $args->{'skip_fields'} || '';
@@ -339,29 +356,75 @@ sub produce {
             @fields = grep { $_->is_foreign_key } @fields;
         }
 
-        my $field_str = join(
-            '\l',
-            map {
-                '-\ '
-                . $_->name
-                . ( $show_datatypes ? '\ ' . $_->data_type : '')
-                . ( $show_sizes && ! $show_datatypes ? '\ ' : '')
-                . ( $show_sizes && $_->data_type =~ /^(VAR)?CHAR2?$/i ? '(' . $_->size . ')' : '')
-                . ( $show_constraints ?
-                    ( $_->is_primary_key || $_->is_foreign_key || $_->is_unique ? '\ [' : '' )
-                    . ( $_->is_primary_key ? 'PK' : '' )
-                    . ( $_->is_primary_key && ($_->is_foreign_key || $_->is_unique) ? ',' : '' )
-                    . ( $_->is_foreign_key ? 'FK' : '' )
-                    . ( $_->is_unique && ($_->is_primary_key || $_->is_foreign_key) ? ',' : '' )
-                    . ( $_->is_unique ? 'U' : '' )
-                    . ( $_->is_primary_key || $_->is_foreign_key || $_->is_unique ? ']' : '' )
-                : '' )
-                . '\ '
-            } @fields
-        ) . '\l';
-        my $label = $show_fields ? "{$table_name|$field_str}" : $table_name;
+        my $label = '{' . $table_name;
+        if ($show_fields) {
+          my $field_str = '';
+          foreach my $field (@fields) {
+            $field_str .= '-\ ' . $field->name;
+            if ($show_datatypes) {
+              my $dt = lc($field->data_type);
+
+              # For the integer type, transform into different types based on
+              # requested size, if a size is given.
+              if ($friendly_ints && $dt eq 'integer' && $field->size) {
+                # Automatically translate to int2, int4, int8
+                # Type (Bits)     Max. Signed           Length
+                # tinyint (8)     128                   3
+                # smallint (16)   32767                 5
+                # int (32)        2147483647            10
+                # bigint (64)     9223372036854775807   19
+                if ($field->size > 10) {
+                  $dt = 'bigint';
+                }
+                elsif ($field->size > 5) {
+                  $dt = 'integer';
+                }
+                elsif ($field->size > 3) {
+                  $dt = 'smallint';
+                }
+                else { # 8 bits
+                  $dt = 'tinyint';
+                }
+              }
+
+              $field_str .= '\ ' . $dt;
+              if ($show_sizes && $field->size && ($dt =~ /^(var)?char2?$/ || $dt eq 'numeric' || $dt eq 'decimal')) {
+                $field_str .= '(' . $field->size . ')';
+              }
+            }
+
+            if ($show_constraints) {
+              my @constraints;
+              push(@constraints, 'PK') if $field->is_primary_key;
+              push(@constraints, 'FK') if $field->is_foreign_key;
+              push(@constraints, 'U')  if $field->is_unique;
+              if (scalar(@constraints)) {
+                $field_str .= '\ [' . join(',\ ', @constraints) . ']';
+              }
+            }
+            $field_str .= '\l';
+          }
+          $label .= '|' . $field_str;
+        }
+
+        if ($show_indexes) {
+          my $index_str = '';
+          foreach my $index ($table->get_indices) {
+            next unless $index->is_valid;
+
+            $index_str .= '*\ ' . $index->name . ': ';
+            $index_str .= join(', ', $index->fields);
+            if ($index->type eq 'UNIQUE') {
+              $index_str .= '\ [U]';
+            }
+            $index_str .= '\l';
+          }
+          $label .= '|' . $index_str;
+        }
+        $label .= '}';
 #        $gv->add_node( $table_name, label => $label );
-        $gv->add_node( $table_name, label => $label, ($node_shape eq 'record' ? ( shape => $node_shape ) : ()) );
+#        $gv->add_node( $table_name, label => $label, ($node_shape eq 'record' ? ( shape => $node_shape ) : ()) );
+        $gv->add_node( $table_name, label => $label, shape => $node_shape );
         debug("Processing table '$table_name'");
 
         debug("Fields = ", join(', ', map { $_->name } @fields));