[Collab-qa-commits] r1544 - in udd/scripts: . pg_autodoc

Lucas Nussbaum lucas at alioth.debian.org
Tue Jul 28 13:36:14 UTC 2009


Author: lucas
Date: 2009-07-28 13:36:12 +0000 (Tue, 28 Jul 2009)
New Revision: 1544

Added:
   udd/scripts/pg_autodoc/
   udd/scripts/pg_autodoc/dia.tmpl
   udd/scripts/pg_autodoc/dot.tmpl
   udd/scripts/pg_autodoc/html.tmpl
   udd/scripts/pg_autodoc/neato.tmpl
   udd/scripts/pg_autodoc/postgresql_autodoc
   udd/scripts/pg_autodoc/xml.tmpl
   udd/scripts/pg_autodoc/zigzag.dia.tmpl
Log:
added pg_autodoc 1.40 so that we can generate the schema with pg 8.4

Added: udd/scripts/pg_autodoc/dia.tmpl
===================================================================
--- udd/scripts/pg_autodoc/dia.tmpl	                        (rev 0)
+++ udd/scripts/pg_autodoc/dia.tmpl	2009-07-28 13:36:12 UTC (rev 1544)
@@ -0,0 +1,212 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
+  <dia:layer name="Background" visible="true">
+<!-- TMPL_LOOP name="schemas" -->
+<!-- TMPL_IF name="number_of_schemas" -->
+    <dia:group>
+<!-- /TMPL_IF name="number_of_schemas" -->
+<!-- TMPL_LOOP name="tables" -->
+    <dia:object type="UML - Class" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->">
+      <dia:attribute name="obj_pos">
+        <dia:point val="0,0"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-0.05,-0.05;16.4,6.65"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="0,0"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="16.350000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="6.6000000000000005"/>
+      </dia:attribute>
+      <dia:attribute name="name">
+        <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table" -->#</dia:string>
+      </dia:attribute>
+<!-- TMPL_IF name="number_of_schemas" -->
+      <dia:attribute name="stereotype">
+        <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="schema" -->#</dia:string>
+      </dia:attribute>
+<!-- /TMPL_IF name="number_of_schemas" -->
+      <dia:attribute name="comment">
+        <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table_comment_dia" -->#</dia:string>
+      </dia:attribute>
+      <dia:attribute name="abstract">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="suppress_attributes">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="suppress_operations">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="visible_attributes">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="visible_comments">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="wrap_operations">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="wrap_after_char">
+        <dia:int val="40"/>
+      </dia:attribute>
+      <dia:attribute name="line_color">
+        <dia:color val="#000000"/>
+      </dia:attribute>
+      <dia:attribute name="fill_color">
+        <dia:color val="#ffffff"/>
+      </dia:attribute>
+      <dia:attribute name="text_color">
+        <dia:color val="#000000"/>
+      </dia:attribute>
+      <dia:attribute name="normal_font">
+        <dia:font family="monospace" style="0" name="Courier"/>
+      </dia:attribute>
+      <dia:attribute name="abstract_font">
+        <dia:font family="monospace" style="88" name="Courier"/>
+      </dia:attribute>
+      <dia:attribute name="polymorphic_font">
+        <dia:font family="monospace" style="8" name="Courier"/>
+      </dia:attribute>
+      <dia:attribute name="classname_font">
+        <dia:font family="sans" style="80" name="Helvetica"/>
+      </dia:attribute>
+      <dia:attribute name="abstract_classname_font">
+        <dia:font family="sans" style="88" name="Helvetica"/>
+      </dia:attribute>
+      <dia:attribute name="comment_font">
+        <dia:font family="sans" style="8" name="Helvetica"/>
+      </dia:attribute>
+      <dia:attribute name="font_height">
+        <dia:real val="0.80000000000000004"/>
+      </dia:attribute>
+      <dia:attribute name="polymorphic_font_height">
+        <dia:real val="0.80000000000000004"/>
+      </dia:attribute>
+      <dia:attribute name="abstract_font_height">
+        <dia:real val="0.80000000000000004"/>
+      </dia:attribute>
+      <dia:attribute name="classname_font_height">
+        <dia:real val="1"/>
+      </dia:attribute>
+      <dia:attribute name="abstract_classname_font_height">
+        <dia:real val="1"/>
+      </dia:attribute>
+      <dia:attribute name="comment_font_height">
+        <dia:real val="1"/>
+      </dia:attribute>
+      <dia:attribute name="attributes">
+<!-- TMPL_LOOP name="columns" -->
+        <dia:composite type="umlattribute">
+          <dia:attribute name="name">
+            <dia:string>#<!-- TMPL_IF name="column_primary_key" -->PK<!-- TMPL_ELSE name="column_primary_key" -->  <!-- /TMPL_IF name="column_primary_key" --><!-- TMPL_VAR ESCAPE="HTML" name="column" -->#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="type">
+            <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_type" -->#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="value">
+<!-- TMPL_IF name="column_default_short" -->
+            <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_default_short" -->#</dia:string>
+<!-- TMPL_ELSE name="column_default_short" -->
+            <dia:string/>
+<!-- /TMPL_IF name="column_default_short" -->
+          </dia:attribute>
+          <dia:attribute name="visibility">
+            <dia:enum val="3"/>
+          </dia:attribute>
+          <dia:attribute name="abstract">
+            <dia:boolean val="false"/>
+          </dia:attribute>
+          <dia:attribute name="class_scope">
+            <dia:boolean val="false"/>
+          </dia:attribute>
+        </dia:composite>
+<!-- /TMPL_LOOP name="columns" -->
+      </dia:attribute>
+<!-- TMPL_IF name="constraints" -->
+      <dia:attribute name="visible_operations">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="operations">
+<!-- TMPL_LOOP name="constraints" -->
+        <dia:composite type="umloperation">
+          <dia:attribute name="name">
+            <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_name" -->#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="visibility">
+            <dia:enum val="3"/>
+          </dia:attribute>
+          <dia:attribute name="abstract">
+            <dia:boolean val="false"/>
+          </dia:attribute>
+          <dia:attribute name="class_scope">
+            <dia:boolean val="false"/>
+          </dia:attribute>
+          <dia:attribute name="parameters">
+            <dia:composite type="umlparameter">
+              <dia:attribute name="name">
+                <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_short" -->#</dia:string>
+              </dia:attribute>
+              <dia:attribute name="type">
+                <dia:string>##</dia:string>
+              </dia:attribute>
+              <dia:attribute name="value">
+                <dia:string/>
+              </dia:attribute>
+              <dia:attribute name="kind">
+                <dia:enum val="0"/>
+              </dia:attribute>
+            </dia:composite>
+          </dia:attribute>
+        </dia:composite>
+<!-- /TMPL_LOOP name="constraints" -->
+      </dia:attribute>
+<!-- TMPL_ELSE name="constraints" -->
+      <dia:attribute name="visible_operations">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="operations"/>
+<!-- /TMPL_IF name="constraints" -->
+      <dia:attribute name="template">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="templates"/>
+    </dia:object>
+<!-- /TMPL_LOOP name="tables" -->
+<!-- TMPL_IF name="number_of_schemas" -->
+    </dia:group>
+<!-- /TMPL_IF name="number_of_schemas" -->
+<!-- /TMPL_LOOP name="schemas" -->
+<!-- TMPL_LOOP name="fk_links" -->
+    <dia:object type="UML - Constraint" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->">
+      <dia:attribute name="obj_pos">
+        <dia:point val="0,3.5"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-0.0515705,2.29861;25.1127,3.55157"/>
+      </dia:attribute>
+      <dia:attribute name="conn_endpoints">
+        <dia:point val="0,3.5"/>
+        <dia:point val="25.05,2.7"/>
+      </dia:attribute>
+      <dia:attribute name="constraint">
+        <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="fk_link_name" -->#</dia:string>
+      </dia:attribute>
+      <dia:attribute name="text_pos">
+        <dia:point val="12.525,3.1"/>
+      </dia:attribute>
+      <dia:attribute name="line_colour">
+        <dia:color val="#000000"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle0_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle0_connection_dia" -->"/>
+        <dia:connection handle="1" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle1_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle1_connection_dia" -->"/>
+      </dia:connections>
+    </dia:object>
+<!-- /TMPL_LOOP name="fk_links" -->
+  </dia:layer>
+</dia:diagram>

Added: udd/scripts/pg_autodoc/dot.tmpl
===================================================================
--- udd/scripts/pg_autodoc/dot.tmpl	                        (rev 0)
+++ udd/scripts/pg_autodoc/dot.tmpl	2009-07-28 13:36:12 UTC (rev 1544)
@@ -0,0 +1,19 @@
+digraph g {
+graph [
+rankdir = "LR",
+concentrate = true,
+ratio = auto
+];
+node [
+fontsize = "10",
+shape = record
+];
+edge [
+];
+<TMPL_LOOP name="schemas"><TMPL_LOOP name="tables"><TMPL_UNLESS name="view_definition">
+"<TMPL_IF name="number_of_schemas"><TMPL_VAR name="schema_dot">.</TMPL_IF name="number_of_schemas"><TMPL_VAR name="table_dot">" [shape = plaintext, label = < <TABLE BORDER="1" CELLBORDER="0" CELLSPACING="0"> <TR ><TD PORT="ltcol0"> </TD> <TD bgcolor="grey90" border="1" COLSPAN="4"> \N </TD> <TD PORT="rtcol0"></TD></TR> <TMPL_LOOP name="columns"> <TR><TD PORT="ltcol<TMPL_VAR name="column_number">" ></TD><TD align="left" > <TMPL_VAR name="column_dot"> </TD><TD align="left" > <TMPL_VAR name="column_type"> </TD><TD align="left" > <TMPL_LOOP name="column_constraints"><TMPL_IF NAME="column_primary_key">PK</TMPL_IF NAME="column_primary_key"></TMPL_LOOP name="column_constraints"> </TD><TD align="left" > <TMPL_LOOP name="column_constraints"><TMPL_IF NAME="column_fk"><TMPL_IF NAME="__first__">FK</TMPL_IF NAME="__first__"></TMPL_IF NAME="column_fk"></TMPL_LOOP name="column_constraints"> </TD><TD align="left" PORT="rtcol<TMPL_VAR name="column_number">"> </TD></TR></TMPL_LOOP name="columns"> </TABLE>> ];
+</TMPL_UNLESS name="view_definition"></TMPL_LOOP name="tables"></TMPL_LOOP name="schemas">
+
+<TMPL_LOOP name="fk_links">
+"<TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle0_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle0_name">":rtcol<TMPL_VAR name="handle0_connection"> -> "<TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle1_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR name="handle1_name">":ltcol<TMPL_VAR name="handle1_connection"> [label="<TMPL_VAR name="fk_link_name_dot">"];</TMPL_LOOP name="fk_links">
+}

Added: udd/scripts/pg_autodoc/html.tmpl
===================================================================
--- udd/scripts/pg_autodoc/html.tmpl	                        (rev 0)
+++ udd/scripts/pg_autodoc/html.tmpl	2009-07-28 13:36:12 UTC (rev 1544)
@@ -0,0 +1,308 @@
+<!-- $Header: /cvsroot/autodoc/autodoc/html.tmpl,v 1.4 2006/05/16 19:01:27 rbt Exp $ -->
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
+   "http://www.w3.org/TR/html4/strict.dtd">
+
+<html>
+  <head>
+    <title>Index for <!-- TMPL_VAR ESCAPE="HTML" name="database" --></title>
+    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+    <style type="text/css">
+	BODY {
+		color:	#000000;
+		background-color: #FFFFFF;
+		font-family: Helvetica, sans-serif;
+	}
+
+	P {
+		margin-top: 5px;
+		margin-bottom: 5px;
+	}
+
+	P.w3ref {
+		font-size: 8pt;
+		font-style: italic;
+		text-align: right;
+	}
+
+	P.detail {
+		font-size: 10pt;
+	}
+
+	.error {
+		color: #FFFFFF;
+		background-color: #FF0000;
+	}
+
+	H1, H2, H3, H4, H5, H6 {
+	}
+
+	OL {
+		list-style-type: upper-alpha;
+	}
+
+	UL.topic {
+		list-style-type: upper-alpha;
+	}
+
+	LI.topic {
+		font-weight : bold;
+	}
+
+	HR {
+		color: #00FF00;
+		background-color: #808080;
+	}
+
+	TABLE {
+		border-width: medium;
+		padding: 3px;
+		background-color: #000000;
+		width: 90%;
+	}
+
+	CAPTION {
+		text-transform: capitalize;
+		font-weight : bold;
+		font-size: 14pt;
+	}
+
+	TH {
+		color: #FFFFFF;
+		background-color: #000000;
+		text-align: left;
+	}
+
+	TR {
+		color: #000000;
+		background-color: #000000;
+		vertical-align: top;
+	}
+
+	TR.tr0 {
+		background-color: #F0F0F0;
+	}
+
+	TR.tr1 {
+		background-color: #D8D8D8;
+	}
+
+	TD {
+		font-size: 12pt;
+	}
+
+	TD.col0 {
+		font-weight : bold;
+		width: 20%;
+	}
+
+	TD.col1 {
+		font-style: italic;
+		width: 15%;
+	}
+
+	TD.col2 {
+		font-size: 12px;
+	}
+    </style>
+    <link rel="stylesheet" type="text/css" media="all" href="all.css">
+    <link rel="stylesheet" type="text/css" media="screen" href="screen.css">
+    <link rel="stylesheet" type="text/css" media="print" href="print.css">
+    <meta HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
+  </head>
+  <body>
+
+    <!-- Primary Index -->
+	<p><!-- TMPL_VAR ESCAPE="HTML" name="database_comment" --><br><br>Dumped on <!-- TMPL_VAR ESCAPE="HTML" name="dumped_on" --></p>
+<h1><a name="index">Index of database - <!-- TMPL_VAR ESCAPE="HTML" name="database" --></a></h1>
+<ul>
+    <!-- TMPL_LOOP name="schemas" -->
+    <li><a name="<!-- TMPL_VAR ESCAPE="HTML" name="schema_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a></li><ul>
+    	<!-- TMPL_LOOP name="tables" --><li><a href="#<!-- TMPL_VAR ESCAPE="URL" name="table_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="table" --></a></li><!-- /TMPL_LOOP name="tables" -->
+  	<!-- TMPL_LOOP name="functions" --><li><a href="#<!-- TMPL_VAR ESCAPE="URL" name="function_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="function" --></a></li><!-- /TMPL_LOOP name="functions" -->
+    </ul>
+    <!-- /TMPL_LOOP name="schemas" -->
+</ul>
+
+    <!-- Schema Creation -->
+    <!-- TMPL_LOOP name="schemas" --><!-- <!-- TMPL_VAR ESCAPE="HTML" name="schema" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" --> -->
+
+		<!-- TMPL_IF name="number_of_schemas" -->
+		<hr>
+		<h1>Schema <!-- TMPL_VAR ESCAPE="HTML" name="schema" --></h1>
+		<!-- TMPL_IF name="schema_comment" -->
+			<p><!-- TMPL_VAR name="schema_comment" --></p>
+		<!-- /TMPL_IF name="schema_comment" -->
+
+		<!-- /TMPL_IF name="number_of_schemas" -->
+		<!-- TMPL_LOOP name="tables" -->
+        <hr>
+		<h2><!-- TMPL_IF name="view_definition" -->View:<!-- TMPL_ELSE -->Table:<!-- /TMPL_IF -->
+			<!-- TMPL_IF name="number_of_schemas" -->
+			<a href="#<!-- TMPL_VAR ESCAPE="URL" name="schema_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a>.<!-- /TMPL_IF name="number_of_schemas" --><a name="<!-- TMPL_VAR ESCAPE="URL" name="table_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="table" --></a>
+		</h2>
+        <!-- TMPL_IF name="table_comment" -->
+         <p><!-- TMPL_VAR ESCAPE="HTML" name="table_comment" --></p>
+        <!-- /TMPL_IF name="table_comment" -->
+
+
+        <table width="100%" cellspacing="0" cellpadding="3">
+                <caption><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --> Structure</caption>
+                <tr>
+                <th>F-Key</th>
+                <th>Name</th>
+                <th>Type</th>
+                <th>Description</th>
+                </tr>
+            <!-- TMPL_LOOP name="columns" -->
+            <tr class="<!-- TMPL_IF name="__odd__" -->tr0<!-- tmpl_else name="__odd__" -->tr1<!-- /TMPL_IF name="__odd__" -->">
+				<td>
+                <!-- TMPL_LOOP name="column_constraints" -->
+                  <!-- TMPL_IF name="column_fk" -->
+                  <a href="#<!-- TMPL_VAR ESCAPE="URL" name="column_fk_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="column_fk_schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="column_fk_table" -->.<!-- TMPL_VAR ESCAPE="HTML" name="column_fk_colnum" --><!-- TMPL_IF name="column_fk_keygroup" -->#<!-- TMPL_VAR name="column_fk_keygroup" --><!-- /TMPL_IF name="column_fk_keygroup" --></a>
+                  <!-- /TMPL_IF name="column_fk" -->
+                <!-- /TMPL_LOOP name="column_constraints" -->
+                </td>
+            	<td><!-- TMPL_VAR ESCAPE="HTML" name="column" --></td>
+            	<td><!-- TMPL_VAR ESCAPE="HTML" name="column_type" --></td>
+                <td><i>
+				<!-- TMPL_LOOP name="column_constraints" -->
+					<!-- TMPL_IF name="column_primary_key" -->PRIMARY KEY
+					<!-- /TMPL_IF name="column_primary_key" -->
+
+					<!-- TMPL_IF name="column_unique" -->
+                       UNIQUE<!-- TMPL_IF name="column_unique_keygroup" -->#<!-- TMPL_VAR name="column_unique_keygroup" --><!-- /TMPL_IF name="column_unique_keygroup" -->
+                    <!-- /TMPL_IF name="column_unique" -->
+				<!-- /TMPL_LOOP name="column_constraints" -->
+
+				<!-- TMPL_IF name="column_constraint_notnull" -->NOT NULL<!-- /TMPL_IF name="column_constraint_notnull" -->
+				<!-- TMPL_IF name="column_default" -->DEFAULT <!-- TMPL_VAR ESCAPE="HTML" name="column_default" --><!-- /TMPL_IF name="column_default" -->
+				</i>
+				<!-- TMPL_IF name="column_comment" --><br><br><!-- TMPL_VAR ESCAPE="HTML" name="column_comment" --><!-- /TMPL_IF name="column_comment" -->
+				</td>
+			 </tr>
+            <!-- /TMPL_LOOP name="columns" -->
+        </table>
+
+        <!-- Inherits -->
+		<!-- TMPL_IF name="inherits" -->
+        <p>Table <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --> Inherits
+        <!-- TMPL_LOOP name="inherits" -->
+           <!-- TMPL_VAR name="index_name" --> <!-- TMPL_VAR name="index_definition" -->
+           <a href="#<!-- TMPL_VAR ESCAPE="URL" name="parent_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="parent_schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="parent_table" --></a>, 
+        <!-- /TMPL_LOOP name="inherits" -->
+        </p>
+		<!-- /TMPL_IF name="inherits" -->
+
+		<!-- TMPL_UNLESS name="view_definition" -->
+		<!-- TMPL_IF name="stats_enabled" -->
+        <p>&nbsp;</p>
+        <table width="100%" cellspacing="0" cellpadding="3">
+         <caption>Statistics</caption>
+         <tr>
+          <th>Total Space (disk usage)</th>
+          <th>Tuple Count</th>
+          <th>Active Space</th>
+          <th>Dead Space</th>
+          <th>Free Space</th>
+         </tr>
+         <tr class="tr0">
+          <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_table_bytes" --></td>
+          <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_tuple_count" --></td>
+          <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_tuple_bytes" --></td>
+          <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_dead_bytes" --></td>
+          <td><!-- TMPL_VAR ESCAPE="HTML" name="stats_free_bytes" --></td>
+         </tr>
+        </table>
+		<!-- /TMPL_IF name="stats_enabled" -->
+		<!-- /TMPL_UNLESS name="view_definition" -->
+
+        <!-- Constraint List -->
+		<!-- TMPL_IF name="constraints" -->
+        <p>&nbsp;</p>
+		<table width="100%" cellspacing="0" cellpadding="3">
+            <caption><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --> Constraints</caption>
+            <tr>
+            	<th>Name</th>
+            	<th>Constraint</th>
+            </tr>
+			<!-- TMPL_LOOP name="constraints" -->
+            <tr class="<!-- TMPL_IF name="__odd__" -->tr0<!-- TMPL_ELSE name="__odd__" -->tr1<!-- /TMPL_IF name="__odd__" -->">
+				<td><!-- TMPL_VAR ESCAPE="HTML" name="constraint_name" --></td>
+                <td><!-- TMPL_VAR ESCAPE="HTML" name="constraint" --></td>
+            </tr>
+			<!-- /TMPL_LOOP name="constraints" -->
+		</table>
+		<!-- /TMPL_IF name="constraints" -->
+
+        <!-- Foreign Key Discovery -->
+		<!-- TMPL_IF name="fk_schemas" -->
+			<p>Tables referencing this one via Foreign Key Constraints:</p>
+		<!-- TMPL_LOOP name="fk_schemas" -->
+			<ul>
+				<li><a href="#<!-- TMPL_VAR ESCAPE="URL" name="fk_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_table" --></a></li>
+			</ul>
+		<!-- /TMPL_LOOP name="fk_schemas" -->
+		<!-- /TMPL_IF name="fk_schemas" -->
+
+    <!-- Indexes -->
+    <!-- TMPL_LOOP name="indexes" -->
+       <!-- TMPL_VAR name="index_name" --> <!-- TMPL_VAR name="index_definition" -->
+    <!-- /TMPL_LOOP name="indexes" -->
+
+	<!-- View Definition -->
+	<!-- TMPL_IF name="view_definition" -->
+	<pre><!-- TMPL_VAR ESCAPE="HTML" name="view_definition" --></pre>
+	<!-- /TMPL_IF name="view_definition" -->
+
+	<!-- List off permissions -->
+	<!-- TMPL_IF name="permissions" -->
+ 	<p>&nbsp;</p>
+	<table width="100%" cellspacing="0" cellpadding="3">
+    	<caption>Permissions which apply to <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="table" --></caption>
+    	<tr>
+    		<th>User</th>
+    		<th><center>Select</center></th>
+    		<th><center>Insert</center></th>
+    		<th><center>Update</center></th>
+    		<th><center>Delete</center></th>
+    		<th><center>Reference</center></th>
+    		<th><center>Rule</center></th>
+    		<th><center>Trigger</center></th>
+    	</tr>
+		<!-- TMPL_LOOP name="permissions" -->
+		<tr class="<!-- TMPL_IF name="__odd__" -->tr0<!-- tmpl_else name="__odd__" -->tr1<!-- /TMPL_IF name="__odd__" -->">
+			<td><!-- TMPL_VAR ESCAPE="HTML" name="user" --></td>
+			<td><!-- TMPL_IF name="select" --><center>&diams;</center><!-- /TMPL_IF name="select" --></td>
+			<td><!-- TMPL_IF name="insert" --><center>&diams;</center><!-- /TMPL_IF name="insert" --></td>
+			<td><!-- TMPL_IF name="update" --><center>&diams;</center><!-- /TMPL_IF name="update" --></td>
+			<td><!-- TMPL_IF name="delete" --><center>&diams;</center><!-- /TMPL_IF name="delete" --></td>
+			<td><!-- TMPL_IF name="references" --><center>&diams;</center><!-- /TMPL_IF name="references" --></td>
+			<td><!-- TMPL_IF name="rule" --><center>&diams;</center><!-- /TMPL_IF name="rule" --></td>
+			<td><!-- TMPL_IF name="trigger" --><center>&diams;</center><!-- /TMPL_IF name="trigger" --></td>
+		</tr>
+		<!-- /TMPL_LOOP name="permissions" -->
+	</table>
+	<!-- /TMPL_IF name="permissions" -->
+
+	<p>
+		<a href="#index">Index</a> -
+		<a href="#<!-- TMPL_VAR ESCAPE="URL" name="schema_sgmlid" -->">Schema <!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a>
+    </p>
+	<!-- /TMPL_LOOP name="tables" -->
+
+	<!-- We've gone through the table structure, now lets take a look at user functions -->
+	<!-- TMPL_LOOP name="functions" -->
+		<hr>
+		<h2>Function:
+			<a href="#<!-- TMPL_VAR ESCAPE="HTML" name="schema_sgmlid" -->"><!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" --></a>.<!-- /TMPL_IF name="number_of_schemas" --><a name="<!-- TMPL_VAR ESCAPE="URL" name="function_sgmlid" -->"><!-- TMPL_VAR ESCAPE="HTML" name="function" --></a>
+		</h2>
+<h3>Returns: <!-- TMPL_VAR ESCAPE="HTML" name="function_returns" --></h3>
+<h3>Language: <!-- TMPL_VAR ESCAPE="HTML" name="function_language" --></h3>
+        <!-- TMPL_IF name="function_comment" --><p><!-- TMPL_VAR ESCAPE="HTML" name="function_comment" --></p><!-- /TMPL_IF name="function_comment" -->
+        <pre><!-- TMPL_IF name="function_source" --><!-- TMPL_VAR ESCAPE="HTML" name="function_source" --><!-- /TMPL_IF name="function_source" --></pre>
+	<!-- /TMPL_LOOP name="functions" -->
+
+<!-- /TMPL_LOOP name="schemas" -->
+<p class="w3ref">Generated by <a href="http://www.rbt.ca/autodoc/">PostgreSQL Autodoc</a></p>
+<p class="w3ref"><a href="http://validator.w3.org/check/referer">W3C HTML 4.01 Strict</a></p>
+</body></html>

Added: udd/scripts/pg_autodoc/neato.tmpl
===================================================================
--- udd/scripts/pg_autodoc/neato.tmpl	                        (rev 0)
+++ udd/scripts/pg_autodoc/neato.tmpl	2009-07-28 13:36:12 UTC (rev 1544)
@@ -0,0 +1,22 @@
+digraph g {
+node [ fontsize = "10", shape = record ];
+edge [];
+<TMPL_LOOP name="schemas"><TMPL_LOOP name="tables"><TMPL_UNLESS
+name="view_definition">
+"<TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="schema_dot">.</TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="table_dot">" [shape = record, label = "{<col0> \N| <TMPL_LOOP
+name="columns"><TMPL_VAR name="column_dot">:  <TMPL_VAR
+name="column_type">\l</TMPL_LOOP name="columns">}" ];
+</TMPL_UNLESS name="view_definition"></TMPL_LOOP
+name="tables"></TMPL_LOOP name="schemas">
+<TMPL_LOOP name="fk_links">
+"<TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="handle0_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="handle0_name">" -> "<TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="handle1_schema">.</TMPL_IF name="number_of_schemas"><TMPL_VAR
+name="handle1_name">" [label="<TMPL_VAR
+name="fk_link_name_dot">"];</TMPL_LOOP name="fk_links">
+}
+
+

Added: udd/scripts/pg_autodoc/postgresql_autodoc
===================================================================
--- udd/scripts/pg_autodoc/postgresql_autodoc	                        (rev 0)
+++ udd/scripts/pg_autodoc/postgresql_autodoc	2009-07-28 13:36:12 UTC (rev 1544)
@@ -0,0 +1,1874 @@
+#!/usr/bin/perl
+# -- # -*- Perl -*-w
+# $Header: /cvsroot/autodoc/autodoc/postgresql_autodoc.pl,v 1.27 2009/05/01 02:13:59 rbt Exp $
+#  Imported 1.22 2002/02/08 17:09:48 into sourceforge
+
+# Postgres Auto-Doc Version 1.40
+
+# License
+# -------
+# Copyright (c) 2001-2009, Rod Taylor
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1.   Redistributions of source code must retain the above copyright
+#      notice, this list of conditions and the following disclaimer.
+#
+# 2.   Redistributions in binary form must reproduce the above
+#      copyright notice, this list of conditions and the following
+#      disclaimer in the documentation and/or other materials provided
+#      with the distribution.
+#
+# 3.   Neither the name of the InQuent Technologies Inc. nor the names
+#      of its contributors may be used to endorse or promote products
+#      derived from this software without specific prior written
+#      permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FREEBSD
+# PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+# About Project
+# -------------
+# Various details about the project and related items can be found at
+# the website
+#
+# http://www.rbt.ca/autodoc/
+
+use strict;
+use warnings;
+
+use DBI;
+use Fcntl;
+
+# Allows file templates
+use HTML::Template;
+
+# Allow reading a password from stdin
+use Term::ReadKey;
+
+sub main($) {
+    my ($ARGV) = @_;
+
+    my %db;
+
+    # The templates path
+    # /usr/share/postgresql_autodoc will be replaced by make in the build phase
+    my $template_path = '/usr/share/postgresql_autodoc';
+
+    # Setup the default connection variables based on the environment
+    my $dbuser = $ENV{'PGUSER'};
+    $dbuser ||= $ENV{'USER'};
+
+    my $database = $ENV{'PGDATABASE'};
+    $database ||= $dbuser;
+
+    my $dbhost = $ENV{'PGHOST'};
+    $dbhost ||= "";
+
+    my $dbport = $ENV{'PGPORT'};
+    $dbport ||= "";
+
+    # Determine whether we need a password to connect
+    my $needpass = 0;
+
+    my $dbpass               = "";
+    my $output_filename_base = $database;
+
+    # Tracking variables
+    my $dbisset   = 0;
+    my $fileisset = 0;
+
+    my $only_schema;
+    my $only_matching;
+
+    my $table_out;
+
+    my $wanted_output = undef;    # means all types
+
+    my $statistics = 0;
+
+    # Fetch base and dirnames.  Useful for Usage()
+    my $basename = $0;
+    my $dirname  = $0;
+    $basename =~ s|^.*/([^/]+)$|$1|;
+    $dirname  =~ s|^(.*)/[^/]+$|$1|;
+
+    # If template_path isn't defined, lets set it ourselves
+    $template_path = $dirname if ( !defined($template_path) );
+
+    for ( my $i = 0 ; $i <= $#ARGV ; $i++ ) {
+      ARGPARSE: for ( $ARGV[$i] ) {
+
+            # Set the database
+            /^-d$/ && do {
+                $database = $ARGV[ ++$i ];
+                $dbisset  = 1;
+                if ( !$fileisset ) {
+                    $output_filename_base = $database;
+                }
+                last;
+            };
+
+            # Set the user
+            /^-[uU]$/ && do {
+                $dbuser = $ARGV[ ++$i ];
+                if ( !$dbisset ) {
+                    $database = $dbuser;
+                    if ( !$fileisset ) {
+                        $output_filename_base = $database;
+                    }
+                }
+                last;
+            };
+
+            # Set the hostname
+            /^-h$/ && do { $dbhost = $ARGV[ ++$i ]; last; };
+
+            # Set the Port
+            /^-p$/ && do { $dbport = $ARGV[ ++$i ]; last; };
+
+            # Set the users password
+            /^--password=/ && do {
+                $dbpass = $ARGV[$i];
+                $dbpass =~ s/^--password=//g;
+                last;
+            };
+
+            # Make sure we get a password before attempting to conenct
+            /^--password$/ && do {
+                $needpass = 1;
+                last;
+            };
+
+            # Set the base of the filename. The extensions pulled
+            # from the templates will be appended to this name
+            /^-f$/ && do {
+                $output_filename_base = $ARGV[ ++$i ];
+                $fileisset            = 1;
+                last;
+            };
+
+            # Set the template directory explicitly
+            /^(-l|--library)$/ && do {
+                $template_path = $ARGV[ ++$i ];
+                last;
+            };
+
+            # Set the output type
+            /^(-t|--type)$/ && do {
+                $wanted_output = $ARGV[ ++$i ];
+                last;
+            };
+
+            # User has requested a single schema dump and provided a pattern
+            /^(-s|--schema)$/ && do {
+                $only_schema = $ARGV[ ++$i ];
+                last;
+            };
+
+            # User has requested only tables/objects matching a pattern
+            /^(-m|--matching)$/ && do {
+                $only_matching = $ARGV[ ++$i ];
+                last;
+            };
+
+            # One might dump a table's set (comma-separated) or just one
+            # If dumping a set of specific tables do NOT dump out the functions
+            # in this database. Generates noise in the output
+            # that most likely isn't wanted. Check for $table_out around the
+            # function gathering location.
+            /^--table=/ && do {
+                my $some_table = $ARGV[$i];
+                $some_table =~ s/^--table=//g;
+
+                my @tables_in = split( ',', $some_table );
+                sub single_quote;
+                $table_out = join( ',', map( single_quote, @tables_in ) );
+
+                last;
+            };
+
+            # Check to see if Statistics have been requested
+            /^--statistics$/ && do {
+                $statistics = 1;
+                last;
+            };
+
+            # Help is wanted, redirect user to usage()
+            /^-\?$/    && do { usage( $basename, $database, $dbuser ); last; };
+            /^--help$/ && do { usage( $basename, $database, $dbuser ); last; };
+        }
+    }
+
+    # If no arguments have been provided, connect to the database anyway but
+    # inform the user of what we're doing.
+    if ( $#ARGV <= 0 ) {
+        print <<Msg
+No arguments set.  Use '$basename --help' for help
+
+Connecting to database '$database' as user '$dbuser'
+Msg
+          ;
+    }
+
+    # If needpass has been set but no password was provided, prompt the user
+    # for a password.
+    if ( $needpass and not $dbpass ) {
+        print "Password: ";
+        ReadMode 'noecho';
+        $dbpass = ReadLine 0;
+        chomp $dbpass;
+        ReadMode 'normal';
+        print "\n";
+    }
+
+    # Database Connection
+    my $dsn = "dbi:Pg:dbname=$database";
+    $dsn .= ";host=$dbhost" if ( "$dbhost" ne "" );
+    $dsn .= ";port=$dbport" if ( "$dbport" ne "" );
+
+    info_collect( [ $dsn, $dbuser, $dbpass ],
+        \%db, $database, $only_schema, $only_matching, $statistics,
+        $table_out );
+
+    # Write out *ALL* templates
+    write_using_templates( \%db, $database, $statistics, $template_path,
+        $output_filename_base, $wanted_output );
+}
+
+##
+# info_collect
+#
+# Pull out all of the applicable information about a specific database
+sub info_collect {
+    my ( $dbConnect, $db, $database, $only_schema, $only_matching, $statistics,
+        $table_out )
+      = @_;
+
+    my $dbh = DBI->connect( @{$dbConnect} )
+      or triggerError("Unable to connect due to: $DBI::errstr");
+
+    $dbh->do("set client_encoding to 'UTF-8'")
+      or triggerError("could not set client_encoding to UTF-8: $DBI::errstr");
+
+    my %struct;
+    $db->{$database}{'STRUCT'} = \%struct;
+    my $struct = $db->{$database}{'STRUCT'};
+
+    # PostgreSQL's version is used to determine what queries are required
+    # to retrieve a given information set.
+    if ( $dbh->{pg_server_version} < 70300 ) {
+        die("PostgreSQL 7.3 and later are supported");
+    }
+
+    # Ensure we only retrieve information for the requested schemas.
+    #
+    # system_schema         -> The primary system schema for a database.
+    #                       Public is used for verions prior to 7.3
+    #
+    # system_schema_list -> The list of schemas which we are not supposed
+    #                       to gather information for.
+    #                        TODO: Merge with system_schema in array form.
+    #
+    # schemapattern      -> The schema the user provided as a command
+    #                       line option.
+    my $schemapattern = '^';
+    my $system_schema = 'pg_catalog';
+    my $system_schema_list =
+      'pg_catalog|pg_toast|pg_temp_[0-9]+|information_schema';
+    if ( defined($only_schema) ) {
+        $schemapattern = '^' . $only_schema . '$';
+    }
+
+    # and only objects matching the specified pattern, if any
+    my $matchpattern = '';
+    if ( defined($only_matching) ) {
+        $matchpattern = $only_matching;
+    }
+
+    #
+    # List of queries which are used to gather information from the
+    # database. The queries differ based on version but should
+    # provide similar output. At some point it should be safe to remove
+    # support for older database versions.
+    #
+
+    # Fetch the description of the database
+    my $sql_Database = q{
+       SELECT pg_catalog.obj_description(oid, 'pg_database') as comment
+         FROM pg_catalog.pg_database
+        WHERE datname = '$database';
+    };
+
+    # Pull out a list of tables, views and special structures.
+    my $sql_Tables = qq{
+       SELECT nspname as namespace
+            , relname as tablename
+            , pg_catalog.pg_get_userbyid(relowner) AS tableowner
+            , pg_class.oid
+            , pg_catalog.obj_description(pg_class.oid, 'pg_class') as table_description
+            , relacl
+            , CASE
+              WHEN relkind = 'r' THEN
+                'table'
+              WHEN relkind = 's' THEN
+                'special'
+              ELSE
+                'view'
+              END as reltype
+            , CASE
+              WHEN relkind = 'v' THEN
+                pg_get_viewdef(pg_class.oid)
+              ELSE
+                NULL
+              END as view_definition
+         FROM pg_catalog.pg_class
+         JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid)
+        WHERE relkind IN ('r', 's', 'v')
+          AND relname ~ '$matchpattern'
+          AND nspname !~ '$system_schema_list'
+          AND nspname ~ '$schemapattern' 
+    };
+    $sql_Tables .= qq{ AND relname IN ($table_out)} if defined($table_out);
+
+    # - uses pg_class.oid
+    my $sql_Columns = q{
+       SELECT attname as column_name
+            , attlen as column_length
+            , CASE
+              WHEN pg_type.typname = 'int4'
+                   AND EXISTS (SELECT TRUE
+                                 FROM pg_catalog.pg_depend
+                                 JOIN pg_catalog.pg_class ON (pg_class.oid = objid)
+                                WHERE refobjsubid = attnum
+                                  AND refobjid = attrelid
+                                  AND relkind = 'S') THEN
+                'serial'
+              WHEN pg_type.typname = 'int8'
+                   AND EXISTS (SELECT TRUE
+                                 FROM pg_catalog.pg_depend
+                                 JOIN pg_catalog.pg_class ON (pg_class.oid = objid)
+                                WHERE refobjsubid = attnum
+                                  AND refobjid = attrelid
+                                  AND relkind = 'S') THEN
+                'bigserial'
+              ELSE
+                pg_catalog.format_type(atttypid, atttypmod)
+              END as column_type
+            , CASE
+              WHEN attnotnull THEN
+                cast('NOT NULL' as text)
+              ELSE
+                cast('' as text)
+              END as column_null
+            , CASE
+              WHEN pg_type.typname IN ('int4', 'int8')
+                   AND EXISTS (SELECT TRUE
+                                 FROM pg_catalog.pg_depend
+                                 JOIN pg_catalog.pg_class ON (pg_class.oid = objid)
+                                WHERE refobjsubid = attnum
+                                  AND refobjid = attrelid
+                                  AND relkind = 'S') THEN
+                NULL
+              ELSE
+                adsrc
+              END as column_default
+            , pg_catalog.col_description(attrelid, attnum) as column_description
+            , attnum
+         FROM pg_catalog.pg_attribute 
+         JOIN pg_catalog.pg_type ON (pg_type.oid = atttypid) 
+    LEFT JOIN pg_catalog.pg_attrdef ON (   attrelid = adrelid 
+                                       AND attnum = adnum)
+        WHERE attnum > 0
+          AND attisdropped IS FALSE
+          AND attrelid = ?;
+    };
+
+    my $sql_Table_Statistics;
+    if ( $statistics == 1 ) {
+        if ( $dbh->{pg_server_version} <= 70300 ) {
+            triggerError(
+                    "Table statistics supported on PostgreSQL 7.4 and later.\n"
+                  . "Remove --statistics flag and try again." );
+        }
+
+        $sql_Table_Statistics = q{
+           SELECT table_len
+                , tuple_count
+                , tuple_len
+                , CAST(tuple_percent AS numeric(20,2)) AS tuple_percent
+                , dead_tuple_count
+                , dead_tuple_len
+                , CAST(dead_tuple_percent AS numeric(20,2)) AS dead_tuple_percent
+                , CAST(free_space AS numeric(20,2)) AS free_space
+                , CAST(free_percent AS numeric(20,2)) AS free_percent
+             FROM pgstattuple(CAST(? AS oid));
+        };
+    }
+
+    my $sql_Indexes = q{
+       SELECT schemaname
+            , tablename
+            , indexname
+            , substring(    indexdef
+                       FROM position('(' IN indexdef) + 1
+                        FOR length(indexdef) - position('(' IN indexdef) - 1
+                       ) AS indexdef
+         FROM pg_catalog.pg_indexes
+        WHERE substring(indexdef FROM 8 FOR 6) != 'UNIQUE'
+          AND schemaname = ?
+          AND tablename = ?;
+    };
+
+    my $sql_Inheritance = qq{
+       SELECT parnsp.nspname AS par_schemaname
+            , parcla.relname AS par_tablename
+            , chlnsp.nspname AS chl_schemaname
+            , chlcla.relname AS chl_tablename
+         FROM pg_catalog.pg_inherits
+         JOIN pg_catalog.pg_class AS chlcla ON (chlcla.oid = inhrelid)
+         JOIN pg_catalog.pg_namespace AS chlnsp ON (chlnsp.oid = chlcla.relnamespace)
+         JOIN pg_catalog.pg_class AS parcla ON (parcla.oid = inhparent)
+         JOIN pg_catalog.pg_namespace AS parnsp ON (parnsp.oid = parcla.relnamespace)
+        WHERE chlnsp.nspname = ?
+          AND chlcla.relname = ?
+          AND chlnsp.nspname ~ '$schemapattern'
+          AND parnsp.nspname ~ '$schemapattern';
+    };
+
+    # Fetch the list of PRIMARY and UNIQUE keys
+    my $sql_Primary_Keys = q{
+       SELECT conname AS constraint_name
+            , pg_catalog.pg_get_indexdef(d.objid) AS constraint_definition
+            , CASE
+              WHEN contype = 'p' THEN
+                'PRIMARY KEY'
+              ELSE
+                'UNIQUE'
+              END as constraint_type
+         FROM pg_catalog.pg_constraint AS c
+         JOIN pg_catalog.pg_depend AS d ON (d.refobjid = c.oid)
+        WHERE contype IN ('p', 'u')
+          AND deptype = 'i'
+          AND conrelid = ?;
+    };
+
+    # FOREIGN KEY fetch
+    #
+    # Don't return the constraint name if it was automatically generated by
+    # PostgreSQL.  The $N (where N is an integer) is not a descriptive enough
+    # piece of information to be worth while including in the various outputs.
+    my $sql_Foreign_Keys = qq{
+       SELECT pg_constraint.oid
+            , pg_namespace.nspname AS namespace
+            , CASE WHEN substring(pg_constraint.conname FROM 1 FOR 1) = '\$' THEN ''
+              ELSE pg_constraint.conname
+              END AS constraint_name
+            , conkey AS constraint_key
+            , confkey AS constraint_fkey
+            , confrelid AS foreignrelid
+         FROM pg_catalog.pg_constraint
+         JOIN pg_catalog.pg_class ON (pg_class.oid = conrelid)
+         JOIN pg_catalog.pg_class AS pc ON (pc.oid = confrelid)
+         JOIN pg_catalog.pg_namespace ON (pg_class.relnamespace = pg_namespace.oid)
+         JOIN pg_catalog.pg_namespace AS pn ON (pn.oid = pc.relnamespace)
+        WHERE contype = 'f'
+          AND conrelid = ?
+          AND pg_namespace.nspname ~ '$schemapattern'
+          AND pn.nspname ~ '$schemapattern';
+    };
+
+    my $sql_Foreign_Key_Arg = q{
+       SELECT attname AS attribute_name
+            , relname AS relation_name
+            , nspname AS namespace
+         FROM pg_catalog.pg_attribute
+         JOIN pg_catalog.pg_class ON (pg_class.oid = attrelid)
+         JOIN pg_catalog.pg_namespace ON (relnamespace = pg_namespace.oid)
+        WHERE attrelid = ?
+          AND attnum = ?;
+    };
+
+    # Fetch CHECK constraints
+    my $sql_Constraint;
+    $sql_Constraint = q{
+       SELECT pg_get_constraintdef(oid) AS constraint_source
+            , conname AS constraint_name
+         FROM pg_constraint
+        WHERE conrelid = ?
+          AND contype = 'c';
+    };
+
+    # Query for function information
+    my $sql_Function;
+    my $sql_FunctionArg;
+    $sql_Function = qq{
+       SELECT proname AS function_name
+            , nspname AS namespace
+            , lanname AS language_name
+            , pg_catalog.obj_description(pg_proc.oid, 'pg_proc') AS comment
+            , proargtypes AS function_args
+            , proargnames AS function_arg_names
+            , prosrc AS source_code
+            , proretset AS returns_set
+            , prorettype AS return_type
+         FROM pg_catalog.pg_proc
+         JOIN pg_catalog.pg_language ON (pg_language.oid = prolang)
+         JOIN pg_catalog.pg_namespace ON (pronamespace = pg_namespace.oid)
+         JOIN pg_catalog.pg_type ON (prorettype = pg_type.oid)
+        WHERE pg_namespace.nspname !~ '$system_schema_list'
+          AND pg_namespace.nspname ~ '$schemapattern'
+          AND proname ~ '$matchpattern'
+          AND proname != 'plpgsql_call_handler';
+    };
+
+    $sql_FunctionArg = q{
+       SELECT nspname AS namespace
+            , replace( pg_catalog.format_type(pg_type.oid, typtypmod)
+                     , nspname ||'.'
+                     , '') AS type_name
+         FROM pg_catalog.pg_type
+         JOIN pg_catalog.pg_namespace ON (pg_namespace.oid = typnamespace)
+        WHERE pg_type.oid = ?;
+    };
+
+    # Fetch schema information.
+    my $sql_Schema = qq{
+       SELECT pg_catalog.obj_description(oid, 'pg_namespace') AS comment
+            , nspname as namespace
+         FROM pg_catalog.pg_namespace
+        WHERE pg_namespace.nspname !~ '$system_schema_list'
+          AND pg_namespace.nspname ~ '$schemapattern';
+    };
+
+    my $sth_Columns          = $dbh->prepare($sql_Columns);
+    my $sth_Constraint       = $dbh->prepare($sql_Constraint);
+    my $sth_Database         = $dbh->prepare($sql_Database);
+    my $sth_Foreign_Keys     = $dbh->prepare($sql_Foreign_Keys);
+    my $sth_Foreign_Key_Arg  = $dbh->prepare($sql_Foreign_Key_Arg);
+    my $sth_Function         = $dbh->prepare($sql_Function);
+    my $sth_FunctionArg      = $dbh->prepare($sql_FunctionArg);
+    my $sth_Indexes          = $dbh->prepare($sql_Indexes);
+    my $sth_Inheritance      = $dbh->prepare($sql_Inheritance);
+    my $sth_Primary_Keys     = $dbh->prepare($sql_Primary_Keys);
+    my $sth_Schema           = $dbh->prepare($sql_Schema);
+    my $sth_Tables           = $dbh->prepare($sql_Tables);
+    my $sth_Table_Statistics = $dbh->prepare($sql_Table_Statistics)
+      if ( $statistics == 1 );
+
+    # Fetch Database info
+    $sth_Database->execute();
+    my $dbinfo = $sth_Database->fetchrow_hashref;
+    if ( defined($dbinfo) ) {
+        $db->{$database}{'COMMENT'} = $dbinfo->{'comment'};
+    }
+
+    # Fetch tables and all things bound to tables
+    $sth_Tables->execute();
+    while ( my $tables = $sth_Tables->fetchrow_hashref ) {
+        my $reloid  = $tables->{'oid'};
+        my $relname = $tables->{'tablename'};
+
+        my $schema = $tables->{'namespace'};
+
+      EXPRESSIONFOUND:
+
+        # Store permissions
+        my $acl = $tables->{'relacl'};
+
+        # Empty acl groups cause serious issues.
+        $acl ||= '';
+
+        # Strip array forming 'junk'.
+        $acl =~ s/^{//g;
+        $acl =~ s/}$//g;
+        $acl =~ s/"//g;
+
+        # Foreach acl
+        foreach ( split( /\,/, $acl ) ) {
+            my ( $user, $raw_permissions ) = split( /=/, $_ );
+
+            if ( defined($raw_permissions) ) {
+                if ( $user eq '' ) {
+                    $user = 'PUBLIC';
+                }
+
+               # The section after the / is the user who granted the permissions
+                my ( $permissions, $granting_user ) =
+                  split( /\//, $raw_permissions );
+
+                # Break down permissions to individual flags
+                if ( $permissions =~ /a/ ) {
+                    $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+                      {'INSERT'} = 1;
+                }
+
+                if ( $permissions =~ /r/ ) {
+                    $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+                      {'SELECT'} = 1;
+                }
+
+                if ( $permissions =~ /w/ ) {
+                    $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+                      {'UPDATE'} = 1;
+                }
+
+                if ( $permissions =~ /d/ ) {
+                    $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+                      {'DELETE'} = 1;
+                }
+
+                if ( $permissions =~ /R/ ) {
+                    $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+                      {'RULE'} = 1;
+                }
+
+                if ( $permissions =~ /x/ ) {
+                    $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+                      {'REFERENCES'} = 1;
+                }
+
+                if ( $permissions =~ /t/ ) {
+                    $struct->{$schema}{'TABLE'}{$relname}{'ACL'}{$user}
+                      {'TRIGGER'} = 1;
+                }
+            }
+        }
+
+        # Primitive Stats, but only if requested
+        if ( $statistics == 1 and $tables->{'reltype'} eq 'table' ) {
+            $sth_Table_Statistics->execute($reloid);
+
+            my $stats = $sth_Table_Statistics->fetchrow_hashref;
+
+            $struct->{$schema}{'TABLE'}{$relname}{'TABLELEN'} =
+              $stats->{'table_len'};
+            $struct->{$schema}{'TABLE'}{$relname}{'TUPLECOUNT'} =
+              $stats->{'tuple_count'};
+            $struct->{$schema}{'TABLE'}{$relname}{'TUPLELEN'} =
+              $stats->{'tuple_len'};
+            $struct->{$schema}{'TABLE'}{$relname}{'DEADTUPLELEN'} =
+              $stats->{'dead_tuple_len'};
+            $struct->{$schema}{'TABLE'}{$relname}{'FREELEN'} =
+              $stats->{'free_space'};
+        }
+
+        # Store the relation type
+        $struct->{$schema}{'TABLE'}{$relname}{'TYPE'} = $tables->{'reltype'};
+
+        # Store table description
+        $struct->{$schema}{'TABLE'}{$relname}{'DESCRIPTION'} =
+          $tables->{'table_description'};
+
+        # Store the view definition
+        $struct->{$schema}{'TABLE'}{$relname}{'VIEW_DEF'} =
+          $tables->{'view_definition'};
+
+        # Store constraints
+        $sth_Constraint->execute($reloid);
+        while ( my $cols = $sth_Constraint->fetchrow_hashref ) {
+            my $constraint_name = $cols->{'constraint_name'};
+            $struct->{$schema}{'TABLE'}{$relname}{'CONSTRAINT'}
+              {$constraint_name} = $cols->{'constraint_source'};
+        }
+
+        $sth_Columns->execute($reloid);
+        my $i = 1;
+        while ( my $cols = $sth_Columns->fetchrow_hashref ) {
+            my $column_name = $cols->{'column_name'};
+            $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+              {'ORDER'} = $cols->{'attnum'};
+            $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+              {'PRIMARY KEY'} = 0;
+            $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+              {'FKTABLE'} = '';
+            $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+              {'TYPE'} = $cols->{'column_type'};
+            $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+              {'NULL'} = $cols->{'column_null'};
+            $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+              {'DESCRIPTION'} = $cols->{'column_description'};
+            $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column_name}
+              {'DEFAULT'} = $cols->{'column_default'};
+        }
+
+        # Pull out both PRIMARY and UNIQUE keys based on the supplied query
+        # and the relation OID.
+        #
+        # Since there may be multiple UNIQUE indexes on a table, we append a
+        # number to the end of the the UNIQUE keyword which shows that they
+        # are a part of a related definition.  I.e UNIQUE_1 goes with UNIQUE_1
+        #
+        $sth_Primary_Keys->execute($reloid);
+        my $unqgroup = 0;
+        while ( my $pricols = $sth_Primary_Keys->fetchrow_hashref ) {
+            my $index_type = $pricols->{'constraint_type'};
+            my $con        = $pricols->{'constraint_name'};
+            my $indexdef   = $pricols->{'constraint_definition'};
+
+            # Fetch the column list
+            my $column_list = $indexdef;
+            $column_list =~ s/.*\(([^)]+)\).*/$1/g;
+
+            # Split our column list and deal with all PRIMARY KEY fields
+            my @collist = split( ',', $column_list );
+
+            # Store the column number in the indextype field.  Anything > 0
+            # indicates the column has this type of constraint applied to it.
+            my $column;
+            my $currentcol = $#collist + 1;
+            my $numcols    = $#collist + 1;
+
+            # Bump group number if there are two or more columns
+            if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) {
+                $unqgroup++;
+            }
+
+            # Record the data to the structure.
+            while ( $column = pop(@collist) ) {
+                $column =~ s/\s$//;
+                $column =~ s/^\s//;
+                $column =~ s/^"//;
+                $column =~ s/"$//;
+
+                $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+                  {$con}{'TYPE'} = $index_type;
+
+                $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+                  {$con}{'COLNUM'} = $currentcol--;
+
+                # Record group number only when a multi-column
+                # constraint is involved
+                if ( $numcols >= 2 && $index_type eq 'UNIQUE' ) {
+                    $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}
+                      {'CON'}{$con}{'KEYGROUP'} = $unqgroup;
+                }
+            }
+        }
+
+        # FOREIGN KEYS like UNIQUE indexes can appear several times in
+        # a table in multi-column format. We use the same trick to
+        # record a numeric association to the foreign key reference.
+        $sth_Foreign_Keys->execute($reloid);
+        my $fkgroup = 0;
+        while ( my $forcols = $sth_Foreign_Keys->fetchrow_hashref ) {
+            my $column_oid = $forcols->{'oid'};
+            my $con        = $forcols->{'constraint_name'};
+
+            # Declare variables for dataload
+            my @keylist;
+            my @fkeylist;
+            my $fschema;
+            my $ftable;
+
+            my $fkey   = $forcols->{'constraint_fkey'};
+            my $keys   = $forcols->{'constraint_key'};
+            my $frelid = $forcols->{'foreignrelid'};
+
+            # Since decent array support was not added until 7.4, and
+            # we want to support 7.3 as well, we parse the text version
+            # of the array by hand rather than combining this and
+            # Foreign_Key_Arg query into a single query.
+
+            my @fkeyset;
+            if ( ref $fkey eq 'ARRAY' ) {
+                @fkeyset = @{$fkey};
+            }
+            else {    # DEPRECATED: DBD::Pg 1.49 and earlier
+                $fkey =~ s/^{//g;
+                $fkey =~ s/}$//g;
+                $fkey =~ s/"//g;
+                @fkeyset = split( /,/, $fkey );
+            }
+
+            my @keyset;
+            if ( ref $keys eq 'ARRAY' ) {
+                @keyset = @{$keys};
+            }
+            else {    # DEPRECATED: DBD::Pg 1.49 and earlier
+                $keys =~ s/^{//g;
+                $keys =~ s/}$//g;
+                $keys =~ s/"//g;
+                @keyset = split( /,/, $keys );
+            }
+
+            # Convert the list of column numbers into column names for the
+            # local side.
+            foreach my $k (@keyset) {
+                $sth_Foreign_Key_Arg->execute( $reloid, $k );
+
+                my $row = $sth_Foreign_Key_Arg->fetchrow_hashref;
+
+                push( @keylist, $row->{'attribute_name'} );
+            }
+
+            # Convert the list of columns numbers into column names
+            # for the referenced side. Grab the table and namespace
+            # while we're here.
+            foreach my $k (@fkeyset) {
+                $sth_Foreign_Key_Arg->execute( $frelid, $k );
+
+                my $row = $sth_Foreign_Key_Arg->fetchrow_hashref;
+
+                push( @fkeylist, $row->{'attribute_name'} );
+                $fschema = $row->{'namespace'};
+                $ftable  = $row->{'relation_name'};
+            }
+
+            # Deal with common catalog issues.
+            die "FKEY $con Broken -- fix your PostgreSQL installation"
+              if $#keylist != $#fkeylist;
+
+            # Load up the array based on the information discovered
+            # using the information retrieval methods above.
+            my $numcols    = $#keylist + 1;
+            my $currentcol = $#keylist + 1;
+
+            # Bump group number if there are two or more columns involved
+            if ( $numcols >= 2 ) {
+                $fkgroup++;
+            }
+
+            # Record the foreign key to structure
+            while ( my $column = pop(@keylist)
+                and my $fkey = pop(@fkeylist) )
+            {
+                $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+                  {$con}{'TYPE'} = 'FOREIGN KEY';
+
+                $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+                  {$con}{'COLNUM'} = $currentcol--;
+
+                $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+                  {$con}{'FKTABLE'} = $ftable;
+                $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+                  {$con}{'FKSCHEMA'} = $fschema;
+                $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}{'CON'}
+                  {$con}{'FK-COL NAME'} = $fkey;
+
+                # Record group number only when a multi-column
+                # constraint is involved
+                if ( $numcols >= 2 ) {
+                    $struct->{$schema}{'TABLE'}{$relname}{'COLUMN'}{$column}
+                      {'CON'}{$con}{'KEYGROUP'} = $fkgroup;
+                }
+            }
+        }
+
+        # Pull out index information
+        $sth_Indexes->execute( $schema, $relname );
+        while ( my $idx = $sth_Indexes->fetchrow_hashref ) {
+            $struct->{$schema}{'TABLE'}{$relname}{'INDEX'}
+              { $idx->{'indexname'} } = $idx->{'indexdef'};
+        }
+
+        # Extract Inheritance information
+        $sth_Inheritance->execute( $schema, $relname );
+        while ( my $inherit = $sth_Inheritance->fetchrow_hashref ) {
+            my $parSch = $inherit->{'par_schemaname'};
+            my $parTab = $inherit->{'par_tablename'};
+            $struct->{$schema}{'TABLE'}{$relname}{'INHERIT'}{$parSch}{$parTab} =
+              1;
+        }
+    }
+
+    # Function Handling
+    $sth_Function->execute();
+    while ( my $functions = $sth_Function->fetchrow_hashref and not $table_out )
+    {
+        my $schema       = $functions->{'namespace'};
+        my $comment      = $functions->{'comment'};
+        my $functionargs = $functions->{'function_args'};
+        my @types        = split( ' ', $functionargs );
+        my $count        = 0;
+
+        # Pre-setup argument names when available.
+        my $argnames = $functions->{'function_arg_names'};
+
+        # Setup full argument types including the parameter name
+        my @parameters;
+        for my $type (@types) {
+            $sth_FunctionArg->execute($type);
+
+            my $hash = $sth_FunctionArg->fetchrow_hashref;
+
+            my $parameter = '';
+            if ($argnames) {
+                $parameter .= sprintf( '%s ', pop( @{$argnames} ) );
+            }
+
+            if ( $hash->{'namespace'} ne $system_schema ) {
+                $parameter .= $hash->{'namespace'} . '.';
+            }
+            $parameter .= $hash->{'type_name'};
+
+            push( @parameters, $parameter );
+        }
+        my $functionname = sprintf( '%s(%s)',
+            $functions->{'function_name'},
+            join( ', ', @parameters ) );
+
+        my $ret_type = $functions->{'returns_set'} ? 'SET OF ' : '';
+        $sth_FunctionArg->execute( $functions->{'return_type'} );
+        my $rhash = $sth_FunctionArg->fetchrow_hashref;
+        $ret_type .= $rhash->{'type_name'};
+
+        $struct->{$schema}{'FUNCTION'}{$functionname}{'COMMENT'} = $comment;
+        $struct->{$schema}{'FUNCTION'}{$functionname}{'SOURCE'} =
+          $functions->{'source_code'};
+        $struct->{$schema}{'FUNCTION'}{$functionname}{'LANGUAGE'} =
+          $functions->{'language_name'};
+        $struct->{$schema}{'FUNCTION'}{$functionname}{'RETURNS'} = $ret_type;
+    }
+
+    # Deal with the Schema
+    $sth_Schema->execute();
+    while ( my $schema = $sth_Schema->fetchrow_hashref ) {
+        my $comment   = $schema->{'comment'};
+        my $namespace = $schema->{'namespace'};
+
+        $struct->{$namespace}{'SCHEMA'}{'COMMENT'} = $comment;
+    }
+
+    $sth_Columns->finish();
+    $sth_Constraint->finish();
+    $sth_Database->finish();
+    $sth_Foreign_Keys->finish();
+    $sth_Foreign_Key_Arg->finish();
+    $sth_Function->finish();
+    $sth_FunctionArg->finish();
+    $sth_Indexes->finish();
+    $sth_Inheritance->finish();
+    $sth_Primary_Keys->finish();
+    $sth_Schema->finish();
+    $sth_Tables->finish();
+    $sth_Table_Statistics->finish()
+      if ( $statistics == 1 );
+
+    $dbh->disconnect;
+
+}
+
+#####
+# write_using_templates
+#
+# Generate structure that HTML::Template requires out of the
+# $struct for table related information, and $struct for
+# the schema and function information
+sub write_using_templates($$$$$) {
+    my ( $db, $database, $statistics, $template_path, $output_filename_base,
+        $wanted_output )
+      = @_;
+    my $struct = $db->{$database}{'STRUCT'};
+
+    my @schemas;
+
+    # Start at 0, increment to 1 prior to use.
+    my $object_id = 0;
+    my %tableids;
+    foreach my $schema ( sort keys %{$struct} ) {
+        my @tables;
+        foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) {
+
+            # Column List
+            my @columns;
+            foreach my $column (
+                sort {
+                    $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a}
+                      {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table}
+                      {'COLUMN'}{$b}{'ORDER'}
+                } keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} }
+              )
+            {
+                my $inferrednotnull = 0;
+
+                # Have a shorter default for places that require it
+                my $shortdefault =
+                  $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                  {'DEFAULT'};
+                $shortdefault =~ s/^(.{17}).{5,}(.{5})$/$1 ... $2/g
+                  if ( defined($shortdefault) );
+
+                # Deal with column constraints
+                my @colconstraints;
+                foreach my $con (
+                    sort keys %{
+                        $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}
+                    }
+                  )
+                {
+                    if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                        {'CON'}{$con}{'TYPE'} eq 'UNIQUE' )
+                    {
+                        my $unq =
+                          $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}{$con}{'TYPE'};
+                        my $unqcol =
+                          $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}{$con}{'COLNUM'};
+                        my $unqgroup =
+                          $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}{$con}{'KEYGROUP'};
+
+                        push @colconstraints,
+                          {
+                            column_unique          => $unq,
+                            column_unique_colnum   => $unqcol,
+                            column_unique_keygroup => $unqgroup,
+                          };
+                    }
+                    elsif (
+                        $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                        {'CON'}{$con}{'TYPE'} eq 'PRIMARY KEY' )
+                    {
+                        $inferrednotnull = 1;
+                        push @colconstraints,
+                          { column_primary_key => 'PRIMARY KEY', };
+                    }
+                    elsif (
+                        $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                        {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY' )
+                    {
+                        my $fksgmlid = sgml_safe_id(
+                            join( '.',
+                                $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+                                  {$column}{'CON'}{$con}{'FKSCHEMA'},
+                                $struct->{$schema}{'TABLE'}{$table}{'TYPE'},
+                                $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+                                  {$column}{'CON'}{$con}{'FKTABLE'} )
+                        );
+
+                        my $fkgroup =
+                          $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}{$con}{'KEYGROUP'};
+                        my $fktable =
+                          $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}{$con}{'FKTABLE'};
+                        my $fkcol =
+                          $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}{$con}{'FK-COL NAME'};
+                        my $fkschema =
+                          $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}{$con}{'FKSCHEMA'};
+
+                        push @colconstraints,
+                          {
+                            column_fk            => 'FOREIGN KEY',
+                            column_fk_colnum     => $fkcol,
+                            column_fk_keygroup   => $fkgroup,
+                            column_fk_schema     => $fkschema,
+                            column_fk_schema_dbk => docbook($fkschema),
+                            column_fk_schema_dot => graphviz($fkschema),
+                            column_fk_sgmlid     => $fksgmlid,
+                            column_fk_table      => $fktable,
+                            column_fk_table_dbk  => docbook($fktable),
+                          };
+
+                        # only have the count if there is more than 1 schema
+                        if ( scalar( keys %{$struct} ) > 1 ) {
+                            $colconstraints[-1]{"number_of_schemas"} =
+                              scalar( keys %{$struct} );
+                        }
+                    }
+                }
+
+                # Generate the Column array
+                push @columns, {
+                    column     => $column,
+                    column_dbk => docbook($column),
+                    column_dot => graphviz($column),
+                    column_default =>
+                      $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                      {'DEFAULT'},
+                    column_default_dbk => docbook(
+                        $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'DEFAULT'}
+                    ),
+                    column_default_short     => $shortdefault,
+                    column_default_short_dbk => docbook($shortdefault),
+
+                    column_comment =>
+                      $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                      {'DESCRIPTION'},
+                    column_comment_dbk => docbook(
+                        $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'DESCRIPTION'}
+                    ),
+
+                    column_number =>
+                      $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                      {'ORDER'},
+
+                    column_type =>
+                      $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                      {'TYPE'},
+                    column_type_dbk => docbook(
+                        $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'TYPE'}
+                    ),
+                    column_type_dot => graphviz(
+                        $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'TYPE'}
+                    ),
+
+                    column_constraints => \@colconstraints,
+                };
+
+                if ( $inferrednotnull == 0 ) {
+                    $columns[-1]{"column_constraint_notnull"} =
+                      $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                      {'NULL'};
+                }
+            }
+
+            # Constraint List
+            my @constraints;
+            foreach my $constraint (
+                sort
+                keys %{ $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'} }
+              )
+            {
+                my $shortcon =
+                  $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'}
+                  {$constraint};
+                $shortcon =~ s/^(.{30}).{5,}(.{5})$/$1 ... $2/g;
+                push @constraints,
+                  {
+                    constraint =>
+                      $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'}
+                      {$constraint},
+                    constraint_dbk => docbook(
+                        $struct->{$schema}{'TABLE'}{$table}{'CONSTRAINT'}
+                          {$constraint}
+                    ),
+                    constraint_name      => $constraint,
+                    constraint_name_dbk  => docbook($constraint),
+                    constraint_short     => $shortcon,
+                    constraint_short_dbk => docbook($shortcon),
+                    table                => $table,
+                    table_dbk            => docbook($table),
+                    table_dot            => graphviz($table),
+                  };
+            }
+
+            # Index List
+            my @indexes;
+            foreach my $index (
+                sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INDEX'} } )
+            {
+                push @indexes,
+                  {
+                    index_definition =>
+                      $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index},
+                    index_definition_dbk => docbook(
+                        $struct->{$schema}{'TABLE'}{$table}{'INDEX'}{$index}
+                    ),
+                    index_name     => $index,
+                    index_name_dbk => docbook($index),
+                    table          => $table,
+                    table_dbk      => docbook($table),
+                    table_dot      => graphviz($table),
+                    schema         => $schema,
+                    schema_dbk     => docbook($schema),
+                    schema_dot     => graphviz($schema),
+                  };
+            }
+
+            my @inherits;
+            foreach my $inhSch (
+                sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'} } )
+            {
+                foreach my $inhTab (
+                    sort keys
+                    %{ $struct->{$schema}{'TABLE'}{$table}{'INHERIT'}{$inhSch} }
+                  )
+                {
+                    push @inherits,
+                      {
+                        table      => $table,
+                        table_dbk  => docbook($table),
+                        table_dot  => graphviz($table),
+                        schema     => $schema,
+                        schema_dbk => docbook($schema),
+                        schema_dot => graphviz($schema),
+                        sgmlid =>
+                          sgml_safe_id( join( '.', $schema, 'table', $table ) ),
+                        parent_sgmlid => sgml_safe_id(
+                            join( '.', $inhSch, 'table', $inhTab )
+                        ),
+                        parent_table      => $inhTab,
+                        parent_table_dbk  => docbook($inhTab),
+                        parent_table_dot  => graphviz($inhTab),
+                        parent_schema     => $inhSch,
+                        parent_schema_dbk => docbook($inhSch),
+                        parent_schema_dot => graphviz($inhSch),
+                      };
+                }
+            }
+
+            # Foreign Key Discovery
+            #
+            # $lastmatch is used to ensure that we only supply a result a
+            # single time and not once for each link found.  Since the
+            # loops are sorted, we only need to track the last element, and
+            # not all supplied elements.
+            my @fk_schemas;
+            my $lastmatch = '';
+            foreach my $fk_schema ( sort keys %{$struct} ) {
+                foreach
+                  my $fk_table ( sort keys %{ $struct->{$fk_schema}{'TABLE'} } )
+                {
+                    foreach my $fk_column (
+                        sort keys
+                        %{ $struct->{$fk_schema}{'TABLE'}{$fk_table}{'COLUMN'} }
+                      )
+                    {
+                        foreach my $fk_con (
+                            sort keys %{
+                                $struct->{$fk_schema}{'TABLE'}{$fk_table}
+                                  {'COLUMN'}{$fk_column}{'CON'}
+                            }
+                          )
+                        {
+                            if ( $struct->{$fk_schema}{'TABLE'}{$fk_table}
+                                {'COLUMN'}{$fk_column}{'CON'}{$fk_con}{'TYPE'}
+                                eq 'FOREIGN KEY'
+                                and $struct->{$fk_schema}{'TABLE'}{$fk_table}
+                                {'COLUMN'}{$fk_column}{'CON'}{$fk_con}
+                                {'FKTABLE'} eq $table
+                                and $struct->{$fk_schema}{'TABLE'}{$fk_table}
+                                {'COLUMN'}{$fk_column}{'CON'}{$fk_con}
+                                {'FKSCHEMA'} eq $schema
+                                and $lastmatch ne "$fk_schema$fk_table" )
+                            {
+                                my $fksgmlid = sgml_safe_id(
+                                    join( '.',
+                                        $fk_schema,
+                                        $struct->{$fk_schema}{'TABLE'}
+                                          {$fk_table}{'TYPE'},
+                                        $fk_table )
+                                );
+                                push @fk_schemas,
+                                  {
+                                    fk_column_number =>
+                                      $struct->{$fk_schema}{'TABLE'}{$fk_table}
+                                      {'COLUMN'}{$fk_column}{'ORDER'},
+                                    fk_sgmlid     => $fksgmlid,
+                                    fk_schema     => $fk_schema,
+                                    fk_schema_dbk => docbook($fk_schema),
+                                    fk_schema_dot => graphviz($fk_schema),
+                                    fk_table      => $fk_table,
+                                    fk_table_dbk  => docbook($fk_table),
+                                    fk_table_dot  => graphviz($fk_table),
+                                  };
+
+                            # only have the count if there is more than 1 schema
+                                if ( scalar( keys %{$struct} ) > 1 ) {
+                                    $fk_schemas[-1]{"number_of_schemas"} =
+                                      scalar( keys %{$struct} );
+                                }
+
+                                $lastmatch = "$fk_schema$fk_table";
+                            }
+                        }
+                    }
+                }
+            }
+
+            # List off permissions
+            my @permissions;
+            foreach my $user (
+                sort keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'} } )
+            {
+                push @permissions,
+                  {
+                    schema     => $schema,
+                    schema_dbk => docbook($schema),
+                    schema_dot => graphviz($schema),
+                    table      => $table,
+                    table_dbk  => docbook($table),
+                    table_dot  => graphviz($table),
+                    user       => $user,
+                    user_dbk   => docbook($user),
+                  };
+
+                # only have the count if there is more than 1 schema
+                if ( scalar( keys %{$struct} ) > 1 ) {
+                    $permissions[-1]{"number_of_schemas"} =
+                      scalar( keys %{$struct} );
+                }
+
+                foreach my $perm (
+                    keys %{ $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user} }
+                  )
+                {
+                    if ( $struct->{$schema}{'TABLE'}{$table}{'ACL'}{$user}
+                        {$perm} == 1 )
+                    {
+                        $permissions[-1]{ lower($perm) } = 1;
+                    }
+                }
+
+            }
+
+            # Increment and record the object ID
+            $tableids{"$schema$table"} = ++$object_id;
+            my $viewdef = sql_prettyprint(
+                $struct->{$schema}{'TABLE'}{$table}{'VIEW_DEF'} );
+
+            # Truncate comment for Dia
+            my $comment_dia =
+              $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'};
+            $comment_dia =~ s/^(.{35}).{5,}(.{5})$/$1 ... $2/g
+              if ( defined($comment_dia) );
+
+            push @tables, {
+                object_id     => $object_id,
+                object_id_dbk => docbook($object_id),
+
+                schema        => $schema,
+                schema_dbk    => docbook($schema),
+                schema_dot    => graphviz($schema),
+                schema_sgmlid => sgml_safe_id( $schema . ".schema" ),
+
+                # Statistics
+                stats_enabled    => $statistics,
+                stats_dead_bytes => useUnits(
+                    $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'}
+                ),
+                stats_dead_bytes_dbk => docbook(
+                    useUnits(
+                        $struct->{$schema}{'TABLE'}{$table}{'DEADTUPLELEN'}
+                    )
+                ),
+                stats_free_bytes =>
+                  useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} ),
+                stats_free_bytes_dbk => docbook(
+                    useUnits( $struct->{$schema}{'TABLE'}{$table}{'FREELEN'} )
+                ),
+                stats_table_bytes =>
+                  useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} ),
+                stats_table_bytes_dbk => docbook(
+                    useUnits( $struct->{$schema}{'TABLE'}{$table}{'TABLELEN'} )
+                ),
+                stats_tuple_count =>
+                  $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'},
+                stats_tuple_count_dbk =>
+                  docbook( $struct->{$schema}{'TABLE'}{$table}{'TUPLECOUNT'} ),
+                stats_tuple_bytes =>
+                  useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} ),
+                stats_tuple_bytes_dbk => docbook(
+                    useUnits( $struct->{$schema}{'TABLE'}{$table}{'TUPLELEN'} )
+                ),
+
+                table        => $table,
+                table_dbk    => docbook($table),
+                table_dot    => graphviz($table),
+                table_sgmlid => sgml_safe_id(
+                    join( '.',
+                        $schema, $struct->{$schema}{'TABLE'}{$table}{'TYPE'},
+                        $table )
+                ),
+                table_comment =>
+                  $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'},
+                table_comment_dbk =>
+                  docbook( $struct->{$schema}{'TABLE'}{$table}{'DESCRIPTION'} ),
+                table_comment_dia   => $comment_dia,
+                view_definition     => $viewdef,
+                view_definition_dbk => docbook($viewdef),
+                columns             => \@columns,
+                constraints         => \@constraints,
+                fk_schemas          => \@fk_schemas,
+                indexes             => \@indexes,
+                inherits            => \@inherits,
+                permissions         => \@permissions,
+            };
+
+            # only have the count if there is more than 1 schema
+            if ( scalar( keys %{$struct} ) > 1 ) {
+                $tables[-1]{"number_of_schemas"} = scalar( keys %{$struct} );
+            }
+        }
+
+        # Dump out list of functions
+        my @functions;
+        foreach my $function ( sort keys %{ $struct->{$schema}{'FUNCTION'} } ) {
+            push @functions,
+              {
+                function     => $function,
+                function_dbk => docbook($function),
+                function_sgmlid =>
+                  sgml_safe_id( join( '.', $schema, 'function', $function ) ),
+                function_comment =>
+                  $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'},
+                function_comment_dbk => docbook(
+                    $struct->{$schema}{'FUNCTION'}{$function}{'COMMENT'}
+                ),
+                function_language =>
+                  uc( $struct->{$schema}{'FUNCTION'}{$function}{'LANGUAGE'} ),
+                function_returns =>
+                  $struct->{$schema}{'FUNCTION'}{$function}{'RETURNS'},
+                function_source =>
+                  $struct->{$schema}{'FUNCTION'}{$function}{'SOURCE'},
+                schema        => $schema,
+                schema_dbk    => docbook($schema),
+                schema_dot    => graphviz($schema),
+                schema_sgmlid => sgml_safe_id( $schema . ".schema" ),
+              };
+
+            # only have the count if there is more than 1 schema
+            if ( scalar( keys %{$struct} ) > 1 ) {
+                $functions[-1]{"number_of_schemas"} = scalar( keys %{$struct} );
+            }
+        }
+
+        push @schemas,
+          {
+            schema         => $schema,
+            schema_dbk     => docbook($schema),
+            schema_dot     => graphviz($schema),
+            schema_sgmlid  => sgml_safe_id( $schema . ".schema" ),
+            schema_comment => $struct->{$schema}{'SCHEMA'}{'COMMENT'},
+            schema_comment_dbk =>
+              docbook( $struct->{$schema}{'SCHEMA'}{'COMMENT'} ),
+            functions => \@functions,
+            tables    => \@tables,
+          };
+
+        # Build the array of schemas
+        if ( scalar( keys %{$struct} ) > 1 ) {
+            $schemas[-1]{"number_of_schemas"} = scalar( keys %{$struct} );
+        }
+    }
+
+    # Link the various components together via the template.
+    my @fk_links;
+    my @fkeys;
+    foreach my $schema ( sort keys %{$struct} ) {
+        foreach my $table ( sort keys %{ $struct->{$schema}{'TABLE'} } ) {
+            foreach my $column (
+                sort {
+                    $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$a}
+                      {'ORDER'} <=> $struct->{$schema}{'TABLE'}{$table}
+                      {'COLUMN'}{$b}{'ORDER'}
+                }
+                keys %{ $struct->{$schema}{'TABLE'}{$table}{'COLUMN'} }
+              )
+            {
+                foreach my $con (
+                    sort keys %{
+                        $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}
+                    }
+                  )
+                {
+
+                    # To prevent a multi-column foreign key from appearing
+                    # several times, we've opted
+                    # to simply display the first column of any given key.
+                    #  Since column numbering always starts at 1
+                    # for foreign keys.
+                    if ( $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                        {'CON'}{$con}{'TYPE'} eq 'FOREIGN KEY'
+                        && $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+                        {$column}{'CON'}{$con}{'COLNUM'} == 1 )
+                    {
+
+                        # Pull out some of the longer keys
+                        my $ref_table =
+                          $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}{$con}{'FKTABLE'};
+                        my $ref_schema =
+                          $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}{$con}{'FKSCHEMA'};
+                        my $ref_column =
+                          $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}{$column}
+                          {'CON'}{$con}{'FK-COL NAME'};
+
+                        # Default values cause these elements to attach
+                        # to the bottom in Dia
+                        # If a KEYGROUP is not defined, it's a single column.
+                        #  Modify the ref_con and key_con variables to attach
+                        # the to the columns connection point directly.
+                        my $ref_con       = 0;
+                        my $key_con       = 0;
+                        my $keycon_offset = 0;
+                        if (
+                            !defined(
+                                $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+                                  {$column}{'CON'}{$con}{'KEYGROUP'}
+                            )
+                          )
+                        {
+                            $ref_con =
+                              $struct->{$ref_schema}{'TABLE'}{$ref_table}
+                              {'COLUMN'}{$ref_column}{'ORDER'} || 0;
+                            $key_con =
+                              $struct->{$schema}{'TABLE'}{$table}{'COLUMN'}
+                              {$column}{'ORDER'} || 0;
+                            $keycon_offset = 1;
+                        }
+
+                        # Bump object_id
+                        $object_id++;
+
+                        push @fk_links,
+                          {
+                            fk_link_name           => $con,
+                            fk_link_name_dbk       => docbook($con),
+                            fk_link_name_dot       => graphviz($con),
+                            handle0_connection     => $key_con,
+                            handle0_connection_dbk => docbook($key_con),
+                            handle0_connection_dia => 6 + ( $key_con * 2 ),
+                            handle0_name           => $table,
+                            handle0_name_dbk       => docbook($table),
+                            handle0_schema         => $schema,
+                            handle0_to => $tableids{"$schema$table"},
+                            handle0_to_dbk =>
+                              docbook( $tableids{"$schema$table"} ),
+                            handle1_connection     => $ref_con,
+                            handle1_connection_dbk => docbook($ref_con),
+                            handle1_connection_dia => 6 +
+                              ( $ref_con * 2 ) +
+                              $keycon_offset,
+                            handle1_name     => $ref_table,
+                            handle1_name_dbk => docbook($ref_table),
+                            handle1_schema   => $ref_schema,
+                            handle1_to => $tableids{"$ref_schema$ref_table"},
+                            handle1_to_dbk =>
+                              docbook( $tableids{"$ref_schema$ref_table"} ),
+                            object_id     => $object_id,
+                            object_id_dbk => docbook($object_id),
+                          };
+
+                        # Build the array of schemas
+                        if ( scalar( keys %{$struct} ) > 1 ) {
+                            $fk_links[-1]{"number_of_schemas"} =
+                              scalar( keys %{$struct} );
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    # Make database level comment information
+    my @timestamp = localtime();
+    my $dumped_on = sprintf( "%04d-%02d-%02d",
+        $timestamp[5] + 1900,
+        $timestamp[4] + 1,
+        $timestamp[3] );
+    my $database_comment = $db->{$database}{'COMMENT'};
+
+    # Loop through each template found in the supplied path.
+    # Output the results of the template as <filename>.<extension>
+    # into the current working directory.
+    my @template_files = glob( $template_path . '/*.tmpl' );
+
+    # Ensure we've told the user if we don't find any files.
+    triggerError("Templates files not found in $template_path")
+      if ( $#template_files < 0 );
+
+    # Process all found templates.
+    foreach my $template_file (@template_files) {
+        ( my $file_extension = $template_file ) =~
+          s/^(?:.*\/|)([^\/]+)\.tmpl$/$1/;
+        next
+          if ( defined($wanted_output) && $file_extension ne $wanted_output );
+        my $output_filename = "$output_filename_base.$file_extension";
+        print "Producing $output_filename from $template_file\n";
+
+        my $template = HTML::Template->new(
+            filename          => $template_file,
+            die_on_bad_params => 0,
+            global_vars       => 0,
+            strict            => 1,
+            loop_context_vars => 1
+        );
+
+        $template->param(
+            database             => $database,
+            database_dbk         => docbook($database),
+            database_sgmlid      => sgml_safe_id($database),
+            database_comment     => $database_comment,
+            database_comment_dbk => docbook($database_comment),
+            dumped_on            => $dumped_on,
+            dumped_on_dbk        => docbook($dumped_on),
+            fk_links             => \@fk_links,
+            schemas              => \@schemas,
+        );
+
+        sysopen( FH, $output_filename, O_WRONLY | O_TRUNC | O_CREAT, 0644 )
+          or die "Can't open $output_filename: $!";
+        print FH $template->output();
+    }
+}
+
+######
+# sgml_safe_id
+#   Safe SGML ID Character replacement
+sub sgml_safe_id($) {
+    my $string = shift;
+
+    # Lets use the keyword ARRAY in place of the square brackets
+    # to prevent duplicating a non-array equivelent
+    $string =~ s/\[\]/ARRAY-/g;
+
+    # Brackets, spaces, commads, underscores are not valid 'id' characters
+    # replace with as few -'s as possible.
+    $string =~ s/[ "',)(_-]+/-/g;
+
+    # Don't want a - at the end either.  It looks silly.
+    $string =~ s/-$//g;
+
+    return ($string);
+}
+
+#####
+# lower
+#    LowerCase the string
+sub lower($) {
+    my $string = shift;
+
+    $string =~ tr/A-Z/a-z/;
+
+    return ($string);
+}
+
+#####
+# useUnits
+#    Tack on base 2 metric units
+sub useUnits($) {
+    my ($value) = @_;
+
+    return '' if ( !defined($value) );
+
+    my @units = ( 'Bytes', 'KiBytes', 'MiBytes', 'GiBytes', 'TiBytes' );
+    my $loop = 0;
+
+    while ( $value >= 1024 ) {
+        $loop++;
+
+        $value = $value / 1024;
+    }
+
+    return ( sprintf( "%.2f %s", $value, $units[$loop] ) );
+}
+
+#####
+# docbook
+#    Docbook output is special in that we may or may not want to escape
+#    the characters inside the string depending on a string prefix.
+sub docbook($) {
+    my $string = shift;
+
+    if ( defined($string) ) {
+        if ( $string =~ /^\@DOCBOOK/ ) {
+            $string =~ s/^\@DOCBOOK//;
+        }
+        else {
+            $string =~ s/&(?!(amp|lt|gr|apos|quot);)/&amp;/g;
+            $string =~ s/</&lt;/g;
+            $string =~ s/>/&gt;/g;
+            $string =~ s/'/&apos;/g;
+            $string =~ s/"/&quot;/g;
+        }
+    }
+    else {
+
+        # Return an empty string when all else fails
+        $string = '';
+    }
+
+    return ($string);
+}
+
+#####
+# graphviz
+#    GraphViz output requires that special characters (like " and whitespace) must be preceeded
+#    by a \ when a part of a lable.
+sub graphviz($) {
+    my $string = shift;
+
+    # Ensure we don't return an least a empty string
+    $string = '' if ( !defined($string) );
+
+    $string =~ s/([\s"'])/\\$1/g;
+
+    return ($string);
+}
+
+#####
+# sql_prettyprint
+#    Clean up SQL into something presentable
+sub sql_prettyprint($) {
+    my $string = shift;
+
+    # If nothing has been sent in, return an empty string
+    if ( !defined($string) ) {
+        return '';
+    }
+
+    # Initialize Result string
+    my $result = '';
+
+    # List of tokens to split on
+    my $tok =
+        "SELECT|FROM|WHERE|HAVING|GROUP BY|ORDER BY|OR|AND|LEFT JOIN|RIGHT JOIN"
+      . "|LEFT OUTER JOIN|LEFT INNER JOIN|INNER JOIN|RIGHT OUTER JOIN|RIGHT INNER JOIN"
+      . "|JOIN|UNION ALL|UNION|EXCEPT|USING|ON|CAST|[\(\),]";
+
+    my $key     = 0;
+    my $bracket = 0;
+    my $depth   = 0;
+    my $indent  = 6;
+
+    # XXX: Split is wrong -- match would do
+    foreach my $elem ( split( /(\"[^\"]*\"|'[^']*'|$tok)/, $string ) ) {
+        my $format;
+
+        # Skip junk tokens
+        if ( $elem =~ /^[\s]?$/ ) {
+            next;
+        }
+
+        # NOTE: Should we drop leading spaces?
+        #    $elem =~ s/^\s//;
+
+        # Close brackets are special
+        # Bring depth in a level
+        if ( $elem =~ /\)/ ) {
+            $depth = $depth - $indent;
+            if ( $key == 1 or $bracket == 1 ) {
+                $format = "%s%s";
+            }
+            else {
+                $format = "%s\n%" . $depth . "s";
+            }
+
+            $key     = 0;
+            $bracket = 0;
+        }
+
+        # Open brackets are special
+        # Bump depth out a level
+        elsif ( $elem =~ /\(/ ) {
+            if ( $key == 1 ) {
+                $format = "%s %s";
+            }
+            else {
+                $format = "%s\n%" . $depth . "s";
+            }
+            $depth   = $depth + $indent;
+            $bracket = 1;
+            $key     = 0;
+        }
+
+        # Key element
+        # Token from our list -- format on left hand side of the equation
+        # when appropriate.
+        elsif ( $elem =~ /$tok/ ) {
+            if ( $key == 1 ) {
+                $format = "%s%s";
+            }
+            else {
+                $format = "%s\n%" . $depth . "s";
+            }
+
+            $key     = 1;
+            $bracket = 0;
+        }
+
+        # Value
+        # Format for right hand side of the equation
+        else {
+            $format = "%s%s";
+
+            $key = 0;
+        }
+
+        # Add the new format string to the result
+        $result = sprintf( $format, $result, $elem );
+    }
+
+    return $result;
+}
+
+##
+# triggerError
+#    Print out a supplied error message and exit the script.
+sub triggerError($) {
+    my ($error) = @_;
+
+    # Test error
+    if ( !defined($error) || $error eq '' ) {
+
+        # Suppress prototype checking in call to self
+        &triggerError("triggerError: Unknown error");
+    }
+    printf( "\n\n%s\n", $error );
+
+    exit 2;
+}
+
+#####
+# usage
+sub usage($$$) {
+    my ( $basename, $database, $dbuser ) = @_;
+    print <<USAGE
+Usage:
+  $basename [options]
+
+Options:
+  -d <dbname>     Specify database name to connect to (default: $database)
+  -f <file>       Specify output file prefix (default: $database)
+  -h <host>       Specify database server host (default: localhost)
+  -p <port>       Specify database server port (default: 5432)
+  -u <username>   Specify database username (default: $dbuser)
+  --password=<pw> Specify database password (default: blank)
+  --password      Have $basename prompt for a password
+
+  -l <path>       Path to the templates (default: /usr/share/postgresql_autodoc)
+  -t <output>     Type of output wanted (default: All in template library)
+
+  -s <schema>     Specify a specific schema to match. Technically this is a regular
+                  expression but anything other than a specific name may have unusual
+                  results.
+
+  -m <regexp>     Show only tables/objects with names matching the specified regular expression.
+
+  --table=<args>  Tables to export. Multiple tables may be provided using a
+                  comma-separated list. I.e. table,table2,table3
+
+  --statistics    In 7.4 and later, with the contrib module pgstattuple installed we
+                  can gather statistics on the tables in the database 
+                  (average size, free space, disk space used, dead tuple counts, etc.)
+                  This is disk intensive on large databases as all pages must be visited.
+USAGE
+      ;
+    exit 1;
+}
+
+sub single_quote {
+    my $attr = $_;
+    $attr =~ s/^\s+|\s+$//g;
+    return qq{'$attr'};
+}
+
+##
+# Kick off execution of main()
+main($ARGV);
+


Property changes on: udd/scripts/pg_autodoc/postgresql_autodoc
___________________________________________________________________
Added: svn:executable
   + *

Added: udd/scripts/pg_autodoc/xml.tmpl
===================================================================
--- udd/scripts/pg_autodoc/xml.tmpl	                        (rev 0)
+++ udd/scripts/pg_autodoc/xml.tmpl	2009-07-28 13:36:12 UTC (rev 1544)
@@ -0,0 +1,204 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!-- $Header: /cvsroot/autodoc/autodoc/xml.tmpl,v 1.2 2006/05/16 19:01:27 rbt Exp $ -->
+
+<book id="database.<!-- TMPL_VAR name="database_sgmlid" -->" xreflabel="<!-- TMPL_VAR name="database_dbk" --> database schema"><title><!-- TMPL_VAR name="database_dbk" --> Model</title>
+
+<!-- TMPL_IF name="database_comment" -->
+<!-- TMPL_VAR name="database_comment_dbk" -->
+<!-- /TMPL_IF name="database_comment" -->
+
+<!-- TMPL_LOOP name="schemas" -->
+  <chapter id="<!-- TMPL_VAR name="schema_sgmlid" -->"
+           xreflabel="<!-- TMPL_VAR name="schema_dbk" -->">
+    <title>Schema <!-- TMPL_VAR name="schema_dbk" --></title>
+    <para><!-- TMPL_VAR name="schema_comment_dbk" --></para>
+
+<!-- TMPL_LOOP name="tables" -->
+      <section id="<!-- TMPL_VAR name="table_sgmlid" -->"
+               xreflabel="<!-- TMPL_VAR name="schema_dbk" -->.<!-- TMPL_VAR name="table_dbk" -->">
+        <title id="<!-- TMPL_VAR name="table_sgmlid" -->-title">
+         <!-- TMPL_IF name="view_definition" -->View:
+         <!-- TMPL_ELSE -->Table:
+         <!-- /TMPL_IF name="view_definition" -->
+         <structname><!-- TMPL_VAR name="table_dbk" --></structname>
+        </title>
+ 
+<!-- TMPL_IF name="table_comment" -->
+        <para>
+          <!-- TMPL_VAR name="table_comment_dbk" -->
+        </para>
+<!-- /TMPL_IF name="table_comment" -->
+
+        <para>
+          <variablelist>
+            <title>
+              Structure of <structname><!-- TMPL_VAR name="table_dbk" --></structname>
+            </title>
+
+<!-- TMPL_LOOP name="columns" -->
+            <varlistentry>
+              <term><structfield><!-- TMPL_VAR name="column_dbk" --></structfield></term>
+              <listitem><para>
+                <type><!-- TMPL_VAR name="column_type_dbk" --></type>
+<!-- TMPL_LOOP name="column_constraints" -->
+<!-- TMPL_IF name="column_primary_key" -->
+                <literal>PRIMARY KEY</literal>
+
+<!-- /TMPL_IF name="column_primary_key" -->
+
+<!-- TMPL_IF name="column_unique" -->
+                      <literal>UNIQUE<!-- TMPL_IF name="column_unique_keygroup" -->#<!-- TMPL_VAR name="column_unique_keygroup" --><!-- /TMPL_IF name="column_unique_keygroup" --></literal>
+<!-- /TMPL_IF name="column_unique" -->
+<!-- /TMPL_LOOP name="column_constraints" -->
+
+<!-- TMPL_IF name="column_constraint_notnull" -->
+                <literal>NOT NULL</literal>
+<!-- /TMPL_IF name="column_constraint_notnull" -->
+
+<!-- TMPL_IF name="column_default" -->
+                <literal>DEFAULT <!-- TMPL_VAR name="column_default_dbk" --></literal>
+<!-- /TMPL_IF name="column_default" -->
+
+<!-- TMPL_LOOP name="column_constraints" -->
+<!-- TMPL_IF name="column_fk" -->
+                <literal>REFERENCES</literal> <xref linkend="<!-- TMPL_VAR name="column_fk_sgmlid" -->"/>
+<!-- /TMPL_IF name="column_fk" -->
+<!-- /TMPL_LOOP name="column_constraints" -->
+              </para>
+<!-- TMPL_IF name="column_comment" -->
+              <para>
+                <!-- TMPL_VAR name="column_comment_dbk" -->
+              </para>
+<!-- /TMPL_IF name="column_comment" -->
+            </listitem>
+          </varlistentry>
+<!-- /TMPL_LOOP name="columns" -->
+        </variablelist>
+
+<!-- TMPL_LOOP name="constraints" -->
+<!-- TMPL_IF name="__FIRST__" -->
+        <variablelist>
+          <title>Constraints on <!-- TMPL_VAR name="table_dbk" --></title>
+<!-- /TMPL_IF name="__FIRST__" -->
+          <varlistentry>
+            <term><!-- TMPL_VAR name="constraint_name_dbk" --></term>
+            <listitem><para><!-- TMPL_VAR name="constraint_dbk" --></para></listitem>
+          </varlistentry>
+<!-- TMPL_IF name="__LAST__" -->
+        </variablelist>
+<!-- /TMPL_IF name="__LAST__" -->
+<!-- /TMPL_LOOP name="constraints" -->
+
+<!-- TMPL_LOOP name="indexes" -->
+<!-- TMPL_IF name="__FIRST__" -->
+        <variablelist>
+          <title>Indexes on <!-- TMPL_VAR name="table_dbk" --></title>
+<!-- /TMPL_IF name="__FIRST__" -->
+          <varlistentry>
+            <term><!-- TMPL_VAR name="index_name_dbk" --></term>
+            <listitem><para><!-- TMPL_VAR name="index_definition_dbk" --></para></listitem>
+          </varlistentry>
+<!-- TMPL_IF name="__LAST__" -->
+        </variablelist>
+<!-- /TMPL_IF name="__LAST__" -->
+<!-- /TMPL_LOOP name="indexes" -->
+
+<!-- TMPL_LOOP name="fk_schemas" -->
+<!-- TMPL_IF name="__FIRST__" -->
+        <itemizedlist>
+          <title>
+            Tables referencing <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_schema_dbk" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="fk_table_dbk" --> via Foreign Key Constraints
+          </title>
+<!-- /TMPL_IF name="__FIRST__" -->
+          <listitem>
+            <para>
+              <xref linkend="<!-- TMPL_VAR name="fk_sgmlid" -->"/>
+            </para>
+          </listitem>
+<!-- TMPL_IF name="__LAST__" -->
+        </itemizedlist>
+<!-- /TMPL_IF name="__LAST__" -->
+<!-- /TMPL_LOOP name="fk_schemas" -->
+
+<!-- TMPL_IF name="view_definition" -->
+        <figure>
+         <title>Definition of view <!-- TMPL_VAR name="table_dbk" --></title>
+         <programlisting><!-- TMPL_VAR name="view_definition_dbk" --></programlisting>
+        </figure>
+<!-- /TMPL_IF name="view_definition" -->
+<!-- TMPL_LOOP name="permissions" -->
+<!-- TMPL_IF name="__FIRST__" -->
+        <variablelist>
+          <title>Permissions on <!-- TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR ESCAPE="HTML" name="schema" -->.<!-- /TMPL_IF name="number_of_schemas" --><!-- TMPL_VAR name="table_dbk" --></title>
+<!-- /TMPL_IF name="__FIRST__" -->
+          <varlistentry>
+            <term><!-- TMPL_VAR name="user_dbk" --></term>
+            <listitem>
+              <para>
+                <simplelist type="inline">
+<!-- TMPL_IF name="select" -->
+                  <member>Select</member>
+<!-- /TMPL_IF name="select" -->
+<!-- TMPL_IF name="insert" -->
+                  <member>Insert</member>
+<!-- /TMPL_IF name="insert" -->
+<!-- TMPL_IF name="update" -->
+                  <member>Update</member>
+<!-- /TMPL_IF name="update" -->
+<!-- TMPL_IF name="delete" -->
+                  <member>Delete</member>
+<!-- /TMPL_IF name="delete" -->
+<!-- TMPL_IF name="rule" -->
+                  <member>Rule</member>
+<!-- /TMPL_IF name="rule" -->
+<!-- TMPL_IF name="references" -->
+                  <member>References</member>
+<!-- /TMPL_IF name="references" -->
+<!-- TMPL_IF name="trigger" -->
+                  <member>Trigger</member>
+<!-- /TMPL_IF name="trigger" -->
+                </simplelist>
+              </para>
+            </listitem>
+          </varlistentry>
+<!-- TMPL_IF name="__LAST__" -->
+        </variablelist>
+<!-- /TMPL_IF name="__LAST__" -->
+<!-- /TMPL_LOOP name="permissions" -->
+
+      </para>
+    </section>
+<!-- /TMPL_LOOP name="tables" -->
+
+<!-- TMPL_LOOP name="functions" -->
+<!-- Function <!-- TMPL_VAR NAME="function" --> -->
+    <section id="<!-- TMPL_VAR NAME="function_sgmlid" -->"
+             xreflabel="<!-- TMPL_VAR NAME="schema_dbk" --><!-- TMPL_VAR NAME="function_dbk"-->">
+      <title id="<!-- TMPL_VAR NAME="function_sgmlid" -->-title">
+       <!-- TMPL_VAR name="function_dbk" -->
+      </title>
+      <titleabbrev id="<!-- TMPL_VAR NAME="function_sgmlid" -->-titleabbrev">
+       <!-- TMPL_VAR name="function_dbk" -->
+      </titleabbrev>
+
+      <para>
+       <segmentedlist>
+        <title>Function Properties</title>
+        <?dbhtml list-presentation="list"?>
+        <segtitle>Language</segtitle>
+        <segtitle>Return Type</segtitle>
+        <seglistitem>
+         <seg><!-- TMPL_VAR ESCAPE="HTML" name="function_language" --></seg>
+         <seg><!-- TMPL_VAR ESCAPE="HTML" name="function_returns" --></seg>
+        </seglistitem>
+       </segmentedlist>
+ 
+       <!-- TMPL_VAR name="function_comment_dbk" -->
+        <programlisting><!-- TMPL_IF name="function_source" --><!-- TMPL_VAR ESCAPE="HTML" name="function_source" --><!-- /TMPL_IF name="function_source" --></programlisting>
+      </para>
+    </section>
+<!-- /TMPL_LOOP name="functions" -->
+  </chapter>
+<!-- /TMPL_LOOP name="schemas" -->
+</book>
+

Added: udd/scripts/pg_autodoc/zigzag.dia.tmpl
===================================================================
--- udd/scripts/pg_autodoc/zigzag.dia.tmpl	                        (rev 0)
+++ udd/scripts/pg_autodoc/zigzag.dia.tmpl	2009-07-28 13:36:12 UTC (rev 1544)
@@ -0,0 +1,224 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<dia:diagram xmlns:dia="http://www.lysator.liu.se/~alla/dia/">
+  <dia:layer name="Background" visible="true">
+<!-- TMPL_LOOP name="schemas" -->
+<!-- TMPL_IF name="number_of_schemas" -->
+    <dia:group>
+<!-- /TMPL_IF name="number_of_schemas" -->
+<!-- TMPL_LOOP name="tables" -->
+    <dia:object type="UML - Class" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->">
+      <dia:attribute name="obj_pos">
+        <dia:point val="0,0"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-0.05,-0.05;16.4,6.65"/>
+      </dia:attribute>
+      <dia:attribute name="elem_corner">
+        <dia:point val="0,0"/>
+      </dia:attribute>
+      <dia:attribute name="elem_width">
+        <dia:real val="16.350000000000001"/>
+      </dia:attribute>
+      <dia:attribute name="elem_height">
+        <dia:real val="6.6000000000000005"/>
+      </dia:attribute>
+      <dia:attribute name="name">
+        <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table" -->#</dia:string>
+      </dia:attribute>
+<!-- TMPL_IF name="number_of_schemas" -->
+      <dia:attribute name="stereotype">
+        <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="schema" -->#</dia:string>
+      </dia:attribute>
+<!-- /TMPL_IF name="number_of_schemas" -->
+      <dia:attribute name="comment">
+        <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="table_comment_dia" -->#</dia:string>
+      </dia:attribute>
+      <dia:attribute name="abstract">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="suppress_attributes">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="suppress_operations">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="visible_attributes">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="visible_comments">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="wrap_operations">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="wrap_after_char">
+        <dia:int val="40"/>
+      </dia:attribute>
+      <dia:attribute name="line_color">
+        <dia:color val="#000000"/>
+      </dia:attribute>
+      <dia:attribute name="fill_color">
+        <dia:color val="#ffffff"/>
+      </dia:attribute>
+      <dia:attribute name="text_color">
+        <dia:color val="#000000"/>
+      </dia:attribute>
+      <dia:attribute name="normal_font">
+        <dia:font family="monospace" style="0" name="Courier"/>
+      </dia:attribute>
+      <dia:attribute name="abstract_font">
+        <dia:font family="monospace" style="88" name="Courier"/>
+      </dia:attribute>
+      <dia:attribute name="polymorphic_font">
+        <dia:font family="monospace" style="8" name="Courier"/>
+      </dia:attribute>
+      <dia:attribute name="classname_font">
+        <dia:font family="sans" style="80" name="Helvetica"/>
+      </dia:attribute>
+      <dia:attribute name="abstract_classname_font">
+        <dia:font family="sans" style="88" name="Helvetica"/>
+      </dia:attribute>
+      <dia:attribute name="comment_font">
+        <dia:font family="sans" style="8" name="Helvetica"/>
+      </dia:attribute>
+      <dia:attribute name="font_height">
+        <dia:real val="0.80000000000000004"/>
+      </dia:attribute>
+      <dia:attribute name="polymorphic_font_height">
+        <dia:real val="0.80000000000000004"/>
+      </dia:attribute>
+      <dia:attribute name="abstract_font_height">
+        <dia:real val="0.80000000000000004"/>
+      </dia:attribute>
+      <dia:attribute name="classname_font_height">
+        <dia:real val="1"/>
+      </dia:attribute>
+      <dia:attribute name="abstract_classname_font_height">
+        <dia:real val="1"/>
+      </dia:attribute>
+      <dia:attribute name="comment_font_height">
+        <dia:real val="1"/>
+      </dia:attribute>
+      <dia:attribute name="attributes">
+<!-- TMPL_LOOP name="columns" -->
+        <dia:composite type="umlattribute">
+          <dia:attribute name="name">
+            <dia:string>#<!-- TMPL_IF name="column_primary_key" -->PK<!-- TMPL_ELSE name="column_primary_key" -->  <!-- /TMPL_IF name="column_primary_key" --><!-- TMPL_VAR ESCAPE="HTML" name="column" -->#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="type">
+            <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_type" -->#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="value">
+<!-- TMPL_IF name="column_default_short" -->
+            <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="column_default_short" -->#</dia:string>
+<!-- TMPL_ELSE name="column_default_short" -->
+            <dia:string/>
+<!-- /TMPL_IF name="column_default_short" -->
+          </dia:attribute>
+          <dia:attribute name="visibility">
+            <dia:enum val="3"/>
+          </dia:attribute>
+          <dia:attribute name="abstract">
+            <dia:boolean val="false"/>
+          </dia:attribute>
+          <dia:attribute name="class_scope">
+            <dia:boolean val="false"/>
+          </dia:attribute>
+        </dia:composite>
+<!-- /TMPL_LOOP name="columns" -->
+      </dia:attribute>
+<!-- TMPL_IF name="constraints" -->
+      <dia:attribute name="visible_operations">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:attribute name="operations">
+<!-- TMPL_LOOP name="constraints" -->
+        <dia:composite type="umloperation">
+          <dia:attribute name="name">
+            <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_name" -->#</dia:string>
+          </dia:attribute>
+          <dia:attribute name="visibility">
+            <dia:enum val="3"/>
+          </dia:attribute>
+          <dia:attribute name="abstract">
+            <dia:boolean val="false"/>
+          </dia:attribute>
+          <dia:attribute name="class_scope">
+            <dia:boolean val="false"/>
+          </dia:attribute>
+          <dia:attribute name="parameters">
+            <dia:composite type="umlparameter">
+              <dia:attribute name="name">
+                <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="constraint_short" -->#</dia:string>
+              </dia:attribute>
+              <dia:attribute name="type">
+                <dia:string>##</dia:string>
+              </dia:attribute>
+              <dia:attribute name="value">
+                <dia:string/>
+              </dia:attribute>
+              <dia:attribute name="kind">
+                <dia:enum val="0"/>
+              </dia:attribute>
+            </dia:composite>
+          </dia:attribute>
+        </dia:composite>
+<!-- /TMPL_LOOP name="constraints" -->
+      </dia:attribute>
+<!-- TMPL_ELSE name="constraints" -->
+      <dia:attribute name="visible_operations">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="operations"/>
+<!-- /TMPL_IF name="constraints" -->
+      <dia:attribute name="template">
+        <dia:boolean val="false"/>
+      </dia:attribute>
+      <dia:attribute name="templates"/>
+    </dia:object>
+<!-- /TMPL_LOOP name="tables" -->
+<!-- TMPL_IF name="number_of_schemas" -->
+    </dia:group>
+<!-- /TMPL_IF name="number_of_schemas" -->
+<!-- /TMPL_LOOP name="schemas" -->
+<!-- TMPL_LOOP name="fk_links" -->
+    <dia:object type="UML - Dependency" version="0" id="O<!-- TMPL_VAR ESCAPE="HTML" name="object_id" -->">
+      <dia:attribute name="obj_pos">
+        <dia:point val="0,3.5"/>
+      </dia:attribute>
+      <dia:attribute name="obj_bb">
+        <dia:rectangle val="-0.0515705,2.29861;25.1127,3.55157"/>
+      </dia:attribute>
+      <dia:attribute name="orth_points">
+        <dia:point val="1.0,1.0"/>
+        <dia:point val="1.0,1.0"/>
+        <dia:point val="1.0,1.0"/>
+      </dia:attribute>
+      <dia:attribute name="orth_orient">
+        <dia:enum val="1"/>
+        <dia:enum val="0"/>
+      </dia:attribute>
+      <dia:attribute name="orth_autoroute">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+
+      <dia:attribute name="line_colour">
+        <dia:color val="#000000"/>
+      </dia:attribute>
+      <dia:attribute name="name">
+        <dia:string>#<!-- TMPL_VAR ESCAPE="HTML" name="fk_link_name" -->#</dia:string>
+      </dia:attribute>
+      <dia:attribute name="stereotype">
+        <dia:string>##</dia:string>
+      </dia:attribute>
+      <dia:attribute name="draw_arrow">
+        <dia:boolean val="true"/>
+      </dia:attribute>
+      <dia:connections>
+        <dia:connection handle="0" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle0_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle0_connection_dia" -->"/>
+        <dia:connection handle="1" to="O<!-- TMPL_VAR ESCAPE="HTML" name="handle1_to" -->" connection="<!-- TMPL_VAR ESCAPE="HTML" name="handle1_connection_dia" -->"/>
+      </dia:connections>
+    </dia:object>
+<!-- /TMPL_LOOP name="fk_links" -->
+  </dia:layer>
+</dia:diagram>




More information about the Collab-qa-commits mailing list