showgraph.in 4.67 KB
Newer Older
1
#!/usr/bin/perl -w
Mac Newbold's avatar
Mac Newbold committed
2

Leigh Stoller's avatar
Leigh Stoller committed
3
#
4
# Copyright (c) 2000-2013 University of Utah and the Flux Group.
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
# 
# {{{EMULAB-LICENSE
# 
# This file is part of the Emulab network testbed software.
# 
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
# 
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public
# License for more details.
# 
# You should have received a copy of the GNU Affero General Public License
# along with this file.  If not, see <http://www.gnu.org/licenses/>.
# 
# }}}
Leigh Stoller's avatar
Leigh Stoller committed
24 25
#

26
if ($#ARGV >= 1 || $#ARGV < 0) {
Mac Newbold's avatar
Mac Newbold committed
27
    #Help mode
28
    print "Usage: schemagraph [output]\n";
Mac Newbold's avatar
Mac Newbold committed
29 30 31 32 33 34 35 36 37 38 39 40 41 42
    print "\n";
    print "This shows a graph of the relations in the Testbed Database.\n";
    print "Fields or columns are shown as ellipses, and entities or tables\n";
    print "are shown as boxes. Direction of arrows is insignificant.\n";
    print "\n";
    print "Fields that connect to only one table are only found in that\n";
    print "table. Fields that connect to two or more tables can be used\n";
    print "to use information from both tables. By making a chain from one\n";
    print "field to a field in another table, you can relate the two\n";
    print "fields together.\n";
    print "\n";
    print "This graph is generated from the current table and column setup\n";
    print "in the actual database, and is always current.\n";
    print "\n";
43
    print "If you get an 'Unable to open display' message, give a display \n";
44 45
    print "parameter (like 'myhost:0') on the command line, and it will \n";
    print "attempt to open it.\n";
Mac Newbold's avatar
Mac Newbold committed
46 47
    die("\n");
}
48 49 50
use lib '@prefix@/lib';
use libtestbed;
use emdb;
Mac Newbold's avatar
Mac Newbold committed
51

52 53
my $display = shift;

Mac Newbold's avatar
Mac Newbold committed
54 55
my $v = 0; # Verbose

56
my @tbls = map { $_ =~ s/.*\.//; $_ } emdb::DBHandle()->tables();
Mac Newbold's avatar
Mac Newbold committed
57

58
my $date = &localtime();
Mac Newbold's avatar
Mac Newbold committed
59 60 61 62

$date =~ s/[ \t]+/ /;
$date =~ s/\n//;

63 64
my $filename="/tmp/showgraph$$";
my $filename2="/tmp/showgraphneato$$";
Mac Newbold's avatar
Mac Newbold committed
65
open(TMP,">$filename");
66
open(TMPN,">$filename2");
Mac Newbold's avatar
Mac Newbold committed
67 68 69

print TMP "graph: {\n  orientation: left_to_right\n".
    "  title: \"Testbed Database Relational Graph - ".$date."\"\n";
70
print TMP "  height: 1000\n  width: 500\n";
Mac Newbold's avatar
Mac Newbold committed
71
print TMP "  priority_phase: yes\n  straight_phase: yes\n";
72
print TMP "  arrowmode: fixed\n";
Mac Newbold's avatar
Mac Newbold committed
73

74 75 76 77 78 79 80
# Adjust the scale here...
print TMP "  display_edge_labels: yes\n  scaling: 0.37\n";

# Use one of the following to control layout... whichever works better...
print TMP "  crossingweight: medianbary\n  splines: yes\n";
#print TMP "  crossingweight: barymedian\n  splines: yes\n";

81 82
print TMPN "graph G {\n";

Mac Newbold's avatar
Mac Newbold committed
83 84 85 86 87 88 89 90 91
my $sth ="";
my $cmd ="";
my @data=();
my $tbl ="";
my $dest="";
my $col ="";
my @tables=();
my %tablecols=();
my @tablelist =();
92
my %forkeys=();
Mac Newbold's avatar
Mac Newbold committed
93 94 95 96

foreach $tbl ( @tbls ) {
    push(@tablelist,$tbl);
    print "Found $tbl:\n" if $v;
97
    if ($sth = DBQueryFatal("describe $tbl") ) {
Mac Newbold's avatar
Mac Newbold committed
98 99 100 101 102
	while ( @data = $sth->fetchrow()) {
	    $col = $data[0];
	    $col =~ s/[0-9\-]+$//;
	    if (!defined($tablecols{$col})) {
		$tablecols{$col}=$tbl;
103 104
		#print TMP "  node: { title: \"$col\" shape: ellipse }\n";
		#print TMPN "{node [label=\"$col\", color=skyblue, shape=ellipse] $col}\n";
Mac Newbold's avatar
Mac Newbold committed
105 106 107 108
		print "  Found $col\n" if $v;
	    } else {
		if (!($tablecols{$col} =~ /^$tbl\b|\.$tbl\.|\.$tbl$/) ) {
		    $tablecols{$col}.=".".$tbl;
109 110 111 112 113
		    if (!defined($forkeys{$col})) {
			print TMP "  node: { title: \"$col\" shape: ellipse }\n";
			print TMPN "{node [label=\"$col\", color=skyblue, shape=ellipse] $col}\n";
		    }
		    $forkeys{$col}=1;
Mac Newbold's avatar
Mac Newbold committed
114 115 116 117 118 119 120
		    print "  Linked $col\n" if $v;
		} #else { print STDERR "It was in there"; }
	    }
	}
    }
}

121
foreach $tbl ( sort @tablelist) {
122 123
    print TMP "  node: { title: \"table_$tbl\" }\n";
    print TMPN "{node [label=\"table_$tbl\", color=green, shape=box] table_$tbl}\n";
Mac Newbold's avatar
Mac Newbold committed
124 125 126
}

foreach $col ( sort keys %tablecols) {
127 128
    @tables= sort split('\.',$tablecols{$col});
    foreach $tbl (sort @tables) {
129 130 131 132 133 134 135 136 137 138 139
	if (defined($forkeys{$col}) && $forkeys{$col}==1) {
	    print TMPN "$col -- table_$tbl [label=\"\"];\n";
	
	    if (@tables < 2 || 
		$tbl=~/^delta_|proj_|dela|rel|nodes|log|exper|res|part|int/i ) {
		print TMP "  edge: { sourcename: \"$col\" ".
		  "targetname: \"table_$tbl\" }\n";
	    } else {
		print TMP "  edge: { sourcename: \"table_$tbl\" ".
		  "targetname: \"$col\" }\n";
	    }
Mac Newbold's avatar
Mac Newbold committed
140 141 142 143 144 145
	}
    }
}

print TMP "}\n";
close TMP;
146 147
print TMPN "}\n";
close TMPN;
Mac Newbold's avatar
Mac Newbold committed
148

149
if ($display ne "") {
150
  system("/usr/X11R6/bin/xvcg -silent -display $display $filename");
151
} else {
152
  system("/usr/X11R6/bin/xvcg -silent $filename");
153
}
154
#exec "/bin/rm $filename";