-
Notifications
You must be signed in to change notification settings - Fork 2
/
db_schema_visualizer.pl
executable file
·94 lines (82 loc) · 2.46 KB
/
db_schema_visualizer.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#!/usr/bin/perl
# db_schema_visualizer.pl
# See: https://joelonsql.com/2016/12/10/pg_catalog-visualized
#
# db_schema_visualizer.pl > pg_catalog.dot
# dot -Tpng -o pg_catalog.png pg_catalog.dot
use strict;
use warnings;
use File::Slurp qw(slurp);
use Data::Dumper;
open my $fh, "<:encoding(utf8)", './doc/src/sgml/catalogs.sgml' or die "$!";
my $table;
my $column;
my $references;
my $pg_catalog_fk_map = {};
while (my $line = <$fh>) {
chomp $line;
if ($line =~ m!^\s+<title><structname>([^<>]+)</> Columns</title>$!) {
$table = $1;
} elsif ($line =~ m!^\s+<entry><structfield>([^<>]+)</structfield></entry>$!) {
$column = $1;
} elsif ($line =~ m!^\s+<entry><type>(oid|regproc)</type></entry>$!) {
} elsif (defined $column && $line =~ m!^\s+<entry><literal><link\ linkend="[^"]+"><structname>([^<>]+)</structname></link>\.oid</literal></entry>$!) {
$references = $1;
if (!defined($pg_catalog_fk_map->{$table}->{$column}))
{
$pg_catalog_fk_map->{$table}->{$column} = $references;
} elsif ($pg_catalog_fk_map->{$table}->{$column} ne $references) {
die "Inconsistent data, $table.$column references both $pg_catalog_fk_map->{$table}->{$column} and $references";
}
$pg_catalog_fk_map->{$table}->{$column} = $references;
if (!defined($pg_catalog_fk_map->{$references})) {
$pg_catalog_fk_map->{$references} = {};
}
} else {
undef($column);
undef($references);
}
}
my $dot = qq!
digraph g {
graph [
rankdir = "LR"
];
node [
fontsize = "16"
shape = "ellipse"
];
edge [
];
!;
foreach my $table (sort keys %{$pg_catalog_fk_map}) {
$dot .= qq!
"$table" [
headlabel = "$table"
label = "$table | <oid> oid|!;
foreach my $column (sort keys %{$pg_catalog_fk_map->{$table}}) {
my $references = $pg_catalog_fk_map->{$table}->{$column};
$dot .= "<$column> $column|";
}
chop($dot);
$dot .= qq!"
shape = "record"
];
!;
}
my $id = 0;
foreach my $table (sort keys %{$pg_catalog_fk_map}) {
foreach my $column (sort keys %{$pg_catalog_fk_map->{$table}}) {
my $references = $pg_catalog_fk_map->{$table}->{$column};
$dot .= qq!
"$table":$column -> "$references":oid [
id = $id
];
!;
$id++;
}
}
$dot .= qq!
}
!;
print $dot;