diff options
| author | guest <guest@f059d3a0-6783-47b7-97ff-1fe0bbf25129> | 2008-09-23 21:29:27 +0000 |
|---|---|---|
| committer | guest <guest@f059d3a0-6783-47b7-97ff-1fe0bbf25129> | 2008-09-23 21:29:27 +0000 |
| commit | d6fa96b4cd67cf4fa18b5b9b6739f9bc2494a9f4 (patch) | |
| tree | 00aa9a27acb6b4c8d9868795a5295e9231f1eb20 /postgresql_autodoc | |
initial import
git-svn-id: http://manut.eu/svn/yalp/trunk@1 f059d3a0-6783-47b7-97ff-1fe0bbf25129
Diffstat (limited to 'postgresql_autodoc')
| -rw-r--r-- | postgresql_autodoc/Makefile | 103 | ||||
| -rw-r--r-- | postgresql_autodoc/config.log | 164 | ||||
| -rw-r--r-- | postgresql_autodoc/config.mk | 13 | ||||
| -rw-r--r-- | postgresql_autodoc/config.mk.in | 13 | ||||
| -rwxr-xr-x | postgresql_autodoc/config.status | 761 | ||||
| -rwxr-xr-x | postgresql_autodoc/configure | 2907 | ||||
| -rw-r--r-- | postgresql_autodoc/configure.ac | 56 | ||||
| -rw-r--r-- | postgresql_autodoc/dia.tmpl | 212 | ||||
| -rw-r--r-- | postgresql_autodoc/dot.tmpl | 19 | ||||
| -rw-r--r-- | postgresql_autodoc/html.tmpl | 308 | ||||
| -rwxr-xr-x | postgresql_autodoc/install-sh | 251 | ||||
| -rw-r--r-- | postgresql_autodoc/neato.tmpl | 22 | ||||
| -rwxr-xr-x | postgresql_autodoc/postgresql_autodoc | 1907 | ||||
| -rwxr-xr-x | postgresql_autodoc/postgresql_autodoc.pl | 1907 | ||||
| -rw-r--r-- | postgresql_autodoc/xml.tmpl | 204 | ||||
| -rw-r--r-- | postgresql_autodoc/zigzag.dia.tmpl | 224 |
16 files changed, 9071 insertions, 0 deletions
diff --git a/postgresql_autodoc/Makefile b/postgresql_autodoc/Makefile new file mode 100644 index 0000000..fdddc1a --- /dev/null +++ b/postgresql_autodoc/Makefile @@ -0,0 +1,103 @@ +# $Header: /cvsroot/autodoc/autodoc/Makefile,v 1.3 2006/05/16 18:57:24 rbt Exp $ + +TEMPLATES = dia.tmpl dot.tmpl html.tmpl neato.tmpl xml.tmpl zigzag.dia.tmpl +BINARY = postgresql_autodoc +CONFIGFILE = config.mk + +RELEASE_FILES = Makefile config.mk.in configure \ + configure.ac $(TEMPLATES) install-sh \ + postgresql_autodoc.pl + +cur-dir := $(shell basename ${PWD}) +REAL_RELEASE_FILES = $(addprefix $(cur-dir)/,$(RELEASE_FILES)) + +# Global dependencies +ALWAYS_DEPEND = Makefile configure $(CONFIGFILE) + + +#### +# Test to see if $(CONFIGFILE) has been generated. If so, include it. Otherwise we assume +# it will be created for us. +has_configmk := $(wildcard $(CONFIGFILE)) + +ifeq ($(has_configmk),$(CONFIGFILE)) +include $(CONFIGFILE) +endif + +#### +# ALL +.PHONY: all +all: $(ALWAYS_DEPEND) $(BINARY) + +#### +# Replace the /usr/bin/env perl with the supplied path +# chmod to make testing easier +$(BINARY): postgresql_autodoc.pl $(CONFIGFILE) + $(SED) -e "s,/usr/bin/env perl,$(PERL)," \ + -e "s,@@TEMPLATE-DIR@@,$(datadir)," \ + postgresql_autodoc.pl > $(BINARY) + -chmod +x $(BINARY) + +#### +# INSTALL Target +.PHONY: install uninstall +install: all $(ALWAYS_DEPEND) + $(INSTALL_SCRIPT) -d $(bindir) + $(INSTALL_SCRIPT) -d $(datadir) + $(INSTALL_SCRIPT) -m 755 $(BINARY) $(bindir) + for entry in $(TEMPLATES) ; \ + do $(INSTALL_SCRIPT) -m 644 $${entry} $(datadir) ; \ + done + +uninstall: + -$(RM) $(bindir)/$(BINARY) + for entry in $(TEMPLATES) ; \ + do $(RM) $(datadir)/$${entry} ; \ + done + -rmdir $(datadir) + -rmdir $(bindir) + +#### +# CLEAN / DISTRIBUTION-CLEAN / MAINTAINER-CLEAN Targets +.PHONY: clean +clean: $(ALWAYS_DEPEND) + $(RM) $(BINARY) + +.PHONY: distribution-clean distclean +distribution-clean distclean: clean + $(RM) $(CONFIGFILE) config.log config.status + $(RM) -r autom4te.cache + $(RM) $(patsubst %.tmpl,*.%,$(wildcard *.tmpl)) + +.PHONY: maintainer-clean +maintainer-clean: distribution-clean + $(RM) configure + +#### +# Build a release +# +# Clean +# Ensure configure is up to date +# Commit any pending elements +# Tar up the results +.PHONY: release +release: distribution-clean configure $(RELEASE_FILES) + @if [ -z ${VERSION} ] ; then \ + echo "-------------------------------------------"; \ + echo "VERSION needs to be specified for a release"; \ + echo "-------------------------------------------"; \ + false; \ + fi + cvs2cl + -cvs commit + cd ../ && tar -czvf postgresql_autodoc-${VERSION}.tar.gz $(REAL_RELEASE_FILES) + +#### +# Build and Run configure files when configure or a template is updated. +configure: configure.ac + autoconf + +# Fix my makefile, then execute myself +$(CONFIGFILE) : config.mk.in configure + ./configure + $(MAKE) $(MAKEFLAGS) diff --git a/postgresql_autodoc/config.log b/postgresql_autodoc/config.log new file mode 100644 index 0000000..5ac7ad9 --- /dev/null +++ b/postgresql_autodoc/config.log @@ -0,0 +1,164 @@ +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by configure, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ ./configure + +## --------- ## +## Platform. ## +## --------- ## + +hostname = tc4200 +uname -m = i686 +uname -r = 2.6.26 +uname -s = Linux +uname -v = #30 PREEMPT Mon Jul 14 10:58:29 CEST 2008 + +/usr/bin/uname -p = Intel(R) Pentium(R) M processor 1.73GHz +/bin/uname -X = unknown + +/bin/arch = unknown +/usr/bin/arch -k = unknown +/usr/convex/getsysinfo = unknown +/usr/bin/hostinfo = unknown +/bin/machine = unknown +/usr/bin/oslevel = unknown +/bin/universe = unknown + +PATH: /usr/local/bin +PATH: /usr/bin +PATH: /bin +PATH: /opt/bin +PATH: /usr/i686-pc-linux-gnu/arm-gentoo-linux-uclibc/gcc-bin/4.1.2 +PATH: /usr/i686-pc-linux-gnu/arm-linux-uclibc/gcc-bin/4.1.2 +PATH: /usr/i686-pc-linux-gnu/gcc-bin/4.3.1 +PATH: /usr/i686-pc-linux-gnu/powerpc-fendt-linux-gnu/gcc-bin/4.2.2 +PATH: /opt/e17/bin +PATH: /usr/kde/3.5/bin +PATH: /usr/qt/3/bin +PATH: /usr/games/bin +PATH: /opt/bin +PATH: /opt/ACE_wrappers/bin +PATH: /opt/ACE_wrappers/TAO/orbsvcs/Naming_Service +PATH: /home/linutronix/scripts +PATH: /home/linutronix/scripts + + +## ----------- ## +## Core tests. ## +## ----------- ## + +configure:1665: checking for a BSD-compatible install +configure:1721: result: /usr/bin/install -c +configure:1737: checking for sed +configure:1756: found /bin/sed +configure:1768: result: /bin/sed +configure:1824: checking for perl +configure:1843: found /usr/bin/perl +configure:1855: result: /usr/bin/perl +configure:1884: checking DBI +configure:1893: result: yes +configure:1884: checking DBD::Pg +configure:1893: result: yes +configure:1884: checking Fcntl +configure:1893: result: yes +configure:1884: checking HTML::Template +configure:1893: result: yes +configure:1884: checking Term::ReadKey +configure:1893: result: yes +configure:2031: creating ./config.status + +## ---------------------- ## +## Running config.status. ## +## ---------------------- ## + +This file was extended by config.status, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = + CONFIG_HEADERS = + CONFIG_LINKS = + CONFIG_COMMANDS = + $ ./config.status + +on tc4200 + +config.status:570: creating config.mk +config.status:705: WARNING: config.mk.in seems to ignore the --datarootdir setting + +## ---------------- ## +## Cache variables. ## +## ---------------- ## + +ac_cv_env_build_alias_set= +ac_cv_env_build_alias_value= +ac_cv_env_host_alias_set= +ac_cv_env_host_alias_value= +ac_cv_env_target_alias_set= +ac_cv_env_target_alias_value= +ac_cv_path_PERL=/usr/bin/perl +ac_cv_path_SED=/bin/sed +ac_cv_path_install='/usr/bin/install -c' + +## ----------------- ## +## Output variables. ## +## ----------------- ## + +DEFS='-DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\"' +ECHO_C='' +ECHO_N='-n' +ECHO_T='' +INSTALL_DATA='${INSTALL} -m 644' +INSTALL_PROGRAM='${INSTALL}' +INSTALL_SCRIPT='${INSTALL}' +LIBOBJS='' +LIBS='' +LTLIBOBJS='' +PACKAGE_BUGREPORT='' +PACKAGE_NAME='' +PACKAGE_STRING='' +PACKAGE_TARNAME='' +PACKAGE_VERSION='' +PATH_SEPARATOR=':' +PERL='/usr/bin/perl' +SED='/bin/sed' +SHELL='/bin/sh' +bindir='${exec_prefix}/bin' +build_alias='' +datadir='${datarootdir}' +datarootdir='${prefix}/share' +docdir='${datarootdir}/doc/${PACKAGE}' +dvidir='${docdir}' +exec_prefix='${prefix}' +host_alias='' +htmldir='${docdir}' +includedir='${prefix}/include' +infodir='${datarootdir}/info' +libdir='${exec_prefix}/lib' +libexecdir='${exec_prefix}/libexec' +localedir='${datarootdir}/locale' +localstatedir='${prefix}/var' +mandir='${datarootdir}/man' +oldincludedir='/usr/include' +pdfdir='${docdir}' +prefix='/usr/local' +program_transform_name='s,x,x,' +psdir='${docdir}' +sbindir='${exec_prefix}/sbin' +sharedstatedir='${prefix}/com' +sysconfdir='${prefix}/etc' +target_alias='' + +## ----------- ## +## confdefs.h. ## +## ----------- ## + +#define PACKAGE_NAME "" +#define PACKAGE_TARNAME "" +#define PACKAGE_VERSION "" +#define PACKAGE_STRING "" +#define PACKAGE_BUGREPORT "" + +configure: exit 0 diff --git a/postgresql_autodoc/config.mk b/postgresql_autodoc/config.mk new file mode 100644 index 0000000..73bd570 --- /dev/null +++ b/postgresql_autodoc/config.mk @@ -0,0 +1,13 @@ +SHELL = /bin/sh + + +# Configure replacements +INSTALL_SCRIPT = /usr/bin/install -c +PERL = /usr/bin/perl +SED = /bin/sed + +# installation directories +prefix = /usr/local +exec_prefix= ${prefix} +bindir = ${exec_prefix}/bin +datadir = ${prefix}/share/postgresql_autodoc diff --git a/postgresql_autodoc/config.mk.in b/postgresql_autodoc/config.mk.in new file mode 100644 index 0000000..ddcee1a --- /dev/null +++ b/postgresql_autodoc/config.mk.in @@ -0,0 +1,13 @@ +SHELL = /bin/sh +VPATH = @srcdir@ + +# Configure replacements +INSTALL_SCRIPT = @INSTALL@ +PERL = @PERL@ +SED = @SED@ + +# installation directories +prefix = @prefix@ +exec_prefix= @exec_prefix@ +bindir = @bindir@ +datadir = @datadir@/postgresql_autodoc diff --git a/postgresql_autodoc/config.status b/postgresql_autodoc/config.status new file mode 100755 index 0000000..5f5e3a1 --- /dev/null +++ b/postgresql_autodoc/config.status @@ -0,0 +1,761 @@ +#! /bin/sh +# Generated by configure. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=${CONFIG_SHELL-/bin/sh} +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +# Files that config.status was made for. +config_files=" config.mk" + +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to <bug-autoconf@gnu.org>." + +ac_cs_version="\ +config.status +configured by ./configure, generated by GNU Autoconf 2.61, + with options \"\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='/home/manut/postgresql_autodoc' +srcdir='.' +INSTALL='/usr/bin/install -c' +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +if $ac_cs_recheck; then + echo "running CONFIG_SHELL=/bin/sh /bin/sh ./configure " $ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=/bin/sh + export CONFIG_SHELL + exec /bin/sh "./configure" $ac_configure_extra_args --no-create --no-recursion +fi + +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +cat >"$tmp/subs-1.sed" <<\CEOF +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +s,@SHELL@,|#_!!_#|/bin/sh,g +s,@PATH_SEPARATOR@,|#_!!_#|:,g +s,@PACKAGE_NAME@,|#_!!_#|,g +s,@PACKAGE_TARNAME@,|#_!!_#|,g +s,@PACKAGE_VERSION@,|#_!!_#|,g +s,@PACKAGE_STRING@,|#_!!_#|,g +s,@PACKAGE_BUGREPORT@,|#_!!_#|,g +s,@exec_prefix@,|#_!!_#|${prefix},g +s,@prefix@,|#_!!_#|/usr/local,g +s,@program_transform_name@,|#_!!_#|s\,x\,x\,,g +s,@bindir@,|#_!!_#|${exec_prefix}/bin,g +s,@sbindir@,|#_!!_#|${exec_prefix}/sbin,g +s,@libexecdir@,|#_!!_#|${exec_prefix}/libexec,g +s,@datarootdir@,|#_!!_#|${prefix}/share,g +s,@datadir@,|#_!!_#|${datarootdir},g +s,@sysconfdir@,|#_!!_#|${prefix}/etc,g +s,@sharedstatedir@,|#_!!_#|${prefix}/com,g +s,@localstatedir@,|#_!!_#|${prefix}/var,g +s,@includedir@,|#_!!_#|${prefix}/include,g +s,@oldincludedir@,|#_!!_#|/usr/include,g +s,@docdir@,|#_!!_#|${datarootdir}/doc/${PACKAGE},g +s,@infodir@,|#_!!_#|${datarootdir}/info,g +s,@htmldir@,|#_!!_#|${docdir},g +s,@dvidir@,|#_!!_#|${docdir},g +s,@pdfdir@,|#_!!_#|${docdir},g +s,@psdir@,|#_!!_#|${docdir},g +s,@libdir@,|#_!!_#|${exec_prefix}/lib,g +s,@localedir@,|#_!!_#|${datarootdir}/locale,g +s,@mandir@,|#_!!_#|${datarootdir}/man,g +s,@DEFS@,|#_!!_#|-DPACKAGE_NAME=\\"\\" -DPACKAGE_TARNAME=\\"\\" -DPACKAGE_VERSION=\\"\\" -DPACKAGE_STRING=\\"\\" -DPACKAGE_BUGREPORT=\\"\\",g +s,@ECHO_C@,|#_!!_#|,g +s,@ECHO_N@,|#_!!_#|-n,g +s,@ECHO_T@,|#_!!_#|,g +s,@LIBS@,|#_!!_#|,g +s,@build_alias@,|#_!!_#|,g +s,@host_alias@,|#_!!_#|,g +s,@target_alias@,|#_!!_#|,g +s,@INSTALL_PROGRAM@,|#_!!_#|${INSTALL},g +s,@INSTALL_SCRIPT@,|#_!!_#|${INSTALL},g +s,@INSTALL_DATA@,|#_!!_#|${INSTALL} -m 644,g +s,@SED@,|#_!!_#|/bin/sed,g +s,@PERL@,|#_!!_#|/usr/bin/perl,g +s,@LIBOBJS@,|#_!!_#|,g +s,@LTLIBOBJS@,|#_!!_#|,g +:end +s/|#_!!_#|//g +CEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} + ac_datarootdir_hack=' + s&@datadir@&${datarootdir}&g + s&@docdir@&${datarootdir}/doc/${PACKAGE}&g + s&@infodir@&${datarootdir}/info&g + s&@localedir@&${datarootdir}/locale&g + s&@mandir@&${datarootdir}/man&g + s&\${datarootdir}&${prefix}/share&g' ;; +esac + sed "/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +} + +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } diff --git a/postgresql_autodoc/configure b/postgresql_autodoc/configure new file mode 100755 index 0000000..776cb9d --- /dev/null +++ b/postgresql_autodoc/configure @@ -0,0 +1,2907 @@ +#! /bin/sh +# From configure.ac Header: /cvsroot/autodoc/autodoc/configure.ac. +# Guess values for system-dependent variables and create Makefiles. +# Generated by GNU Autoconf 2.61. +# +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +# 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +# This configure script is free software; the Free Software Foundation +# gives unlimited permission to copy, distribute and modify it. +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + +if test "x$CONFIG_SHELL" = x; then + if (eval ":") 2>/dev/null; then + as_have_required=yes +else + as_have_required=no +fi + + if test $as_have_required = yes && (eval ": +(as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=\$LINENO + as_lineno_2=\$LINENO + test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && + test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } +") 2> /dev/null; then + : +else + as_candidate_shells= + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + case $as_dir in + /*) + for as_base in sh bash ksh sh5; do + as_candidate_shells="$as_candidate_shells $as_dir/$as_base" + done;; + esac +done +IFS=$as_save_IFS + + + for as_shell in $as_candidate_shells $SHELL; do + # Try only shells that exist, to save several forks. + if { test -f "$as_shell" || test -f "$as_shell.exe"; } && + { ("$as_shell") 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +_ASEOF +}; then + CONFIG_SHELL=$as_shell + as_have_required=yes + if { "$as_shell" 2> /dev/null <<\_ASEOF +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + +: +(as_func_return () { + (exit $1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = "$1" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test $exitcode = 0) || { (exit 1); exit 1; } + +( + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } + +_ASEOF +}; then + break +fi + +fi + + done + + if test "x$CONFIG_SHELL" != x; then + for as_var in BASH_ENV ENV + do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + done + export CONFIG_SHELL + exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} +fi + + + if test $as_have_required = no; then + echo This script requires a shell more modern than all the + echo shells that I found on your system. Please install a + echo modern shell, or manually run the script under such a + echo shell if you do have one. + { (exit 1); exit 1; } +fi + + +fi + +fi + + + +(eval "as_func_return () { + (exit \$1) +} +as_func_success () { + as_func_return 0 +} +as_func_failure () { + as_func_return 1 +} +as_func_ret_success () { + return 0 +} +as_func_ret_failure () { + return 1 +} + +exitcode=0 +if as_func_success; then + : +else + exitcode=1 + echo as_func_success failed. +fi + +if as_func_failure; then + exitcode=1 + echo as_func_failure succeeded. +fi + +if as_func_ret_success; then + : +else + exitcode=1 + echo as_func_ret_success failed. +fi + +if as_func_ret_failure; then + exitcode=1 + echo as_func_ret_failure succeeded. +fi + +if ( set x; as_func_ret_success y && test x = \"\$1\" ); then + : +else + exitcode=1 + echo positional parameters were not saved. +fi + +test \$exitcode = 0") || { + echo No shell found that supports shell functions. + echo Please tell autoconf@gnu.org about your system, + echo including any error possibly output before this + echo message +} + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + + +exec 7<&0 </dev/null 6>&1 + +# Name of the host. +# hostname on some systems (SVR3.2, Linux) returns a bogus exit status, +# so uname gets run too. +ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` + +# +# Initializations. +# +ac_default_prefix=/usr/local +ac_clean_files= +ac_config_libobj_dir=. +LIBOBJS= +cross_compiling=no +subdirs= +MFLAGS= +MAKEFLAGS= +SHELL=${CONFIG_SHELL-/bin/sh} + +# Identity of this package. +PACKAGE_NAME= +PACKAGE_TARNAME= +PACKAGE_VERSION= +PACKAGE_STRING= +PACKAGE_BUGREPORT= + +ac_unique_file="postgresql_autodoc.pl" +ac_subst_vars='SHELL +PATH_SEPARATOR +PACKAGE_NAME +PACKAGE_TARNAME +PACKAGE_VERSION +PACKAGE_STRING +PACKAGE_BUGREPORT +exec_prefix +prefix +program_transform_name +bindir +sbindir +libexecdir +datarootdir +datadir +sysconfdir +sharedstatedir +localstatedir +includedir +oldincludedir +docdir +infodir +htmldir +dvidir +pdfdir +psdir +libdir +localedir +mandir +DEFS +ECHO_C +ECHO_N +ECHO_T +LIBS +build_alias +host_alias +target_alias +INSTALL_PROGRAM +INSTALL_SCRIPT +INSTALL_DATA +SED +PERL +LIBOBJS +LTLIBOBJS' +ac_subst_files='' + ac_precious_vars='build_alias +host_alias +target_alias' + + +# Initialize some variables set by options. +ac_init_help= +ac_init_version=false +# The variables have the same names as the options, with +# dashes changed to underlines. +cache_file=/dev/null +exec_prefix=NONE +no_create= +no_recursion= +prefix=NONE +program_prefix=NONE +program_suffix=NONE +program_transform_name=s,x,x, +silent= +site= +srcdir= +verbose= +x_includes=NONE +x_libraries=NONE + +# Installation directory options. +# These are left unexpanded so users can "make install exec_prefix=/foo" +# and all the variables that are supposed to be based on exec_prefix +# by default will actually change. +# Use braces instead of parens because sh, perl, etc. also accept them. +# (The list follows the same order as the GNU Coding Standards.) +bindir='${exec_prefix}/bin' +sbindir='${exec_prefix}/sbin' +libexecdir='${exec_prefix}/libexec' +datarootdir='${prefix}/share' +datadir='${datarootdir}' +sysconfdir='${prefix}/etc' +sharedstatedir='${prefix}/com' +localstatedir='${prefix}/var' +includedir='${prefix}/include' +oldincludedir='/usr/include' +docdir='${datarootdir}/doc/${PACKAGE}' +infodir='${datarootdir}/info' +htmldir='${docdir}' +dvidir='${docdir}' +pdfdir='${docdir}' +psdir='${docdir}' +libdir='${exec_prefix}/lib' +localedir='${datarootdir}/locale' +mandir='${datarootdir}/man' + +ac_prev= +ac_dashdash= +for ac_option +do + # If the previous option needs an argument, assign it. + if test -n "$ac_prev"; then + eval $ac_prev=\$ac_option + ac_prev= + continue + fi + + case $ac_option in + *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; + *) ac_optarg=yes ;; + esac + + # Accept the important Cygnus configure options, so we can diagnose typos. + + case $ac_dashdash$ac_option in + --) + ac_dashdash=yes ;; + + -bindir | --bindir | --bindi | --bind | --bin | --bi) + ac_prev=bindir ;; + -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) + bindir=$ac_optarg ;; + + -build | --build | --buil | --bui | --bu) + ac_prev=build_alias ;; + -build=* | --build=* | --buil=* | --bui=* | --bu=*) + build_alias=$ac_optarg ;; + + -cache-file | --cache-file | --cache-fil | --cache-fi \ + | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) + ac_prev=cache_file ;; + -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ + | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) + cache_file=$ac_optarg ;; + + --config-cache | -C) + cache_file=config.cache ;; + + -datadir | --datadir | --datadi | --datad) + ac_prev=datadir ;; + -datadir=* | --datadir=* | --datadi=* | --datad=*) + datadir=$ac_optarg ;; + + -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ + | --dataroo | --dataro | --datar) + ac_prev=datarootdir ;; + -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ + | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) + datarootdir=$ac_optarg ;; + + -disable-* | --disable-*) + ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=no ;; + + -docdir | --docdir | --docdi | --doc | --do) + ac_prev=docdir ;; + -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) + docdir=$ac_optarg ;; + + -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) + ac_prev=dvidir ;; + -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) + dvidir=$ac_optarg ;; + + -enable-* | --enable-*) + ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid feature name: $ac_feature" >&2 + { (exit 1); exit 1; }; } + ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` + eval enable_$ac_feature=\$ac_optarg ;; + + -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ + | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ + | --exec | --exe | --ex) + ac_prev=exec_prefix ;; + -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ + | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ + | --exec=* | --exe=* | --ex=*) + exec_prefix=$ac_optarg ;; + + -gas | --gas | --ga | --g) + # Obsolete; use --with-gas. + with_gas=yes ;; + + -help | --help | --hel | --he | -h) + ac_init_help=long ;; + -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) + ac_init_help=recursive ;; + -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) + ac_init_help=short ;; + + -host | --host | --hos | --ho) + ac_prev=host_alias ;; + -host=* | --host=* | --hos=* | --ho=*) + host_alias=$ac_optarg ;; + + -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) + ac_prev=htmldir ;; + -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ + | --ht=*) + htmldir=$ac_optarg ;; + + -includedir | --includedir | --includedi | --included | --include \ + | --includ | --inclu | --incl | --inc) + ac_prev=includedir ;; + -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ + | --includ=* | --inclu=* | --incl=* | --inc=*) + includedir=$ac_optarg ;; + + -infodir | --infodir | --infodi | --infod | --info | --inf) + ac_prev=infodir ;; + -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) + infodir=$ac_optarg ;; + + -libdir | --libdir | --libdi | --libd) + ac_prev=libdir ;; + -libdir=* | --libdir=* | --libdi=* | --libd=*) + libdir=$ac_optarg ;; + + -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ + | --libexe | --libex | --libe) + ac_prev=libexecdir ;; + -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ + | --libexe=* | --libex=* | --libe=*) + libexecdir=$ac_optarg ;; + + -localedir | --localedir | --localedi | --localed | --locale) + ac_prev=localedir ;; + -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) + localedir=$ac_optarg ;; + + -localstatedir | --localstatedir | --localstatedi | --localstated \ + | --localstate | --localstat | --localsta | --localst | --locals) + ac_prev=localstatedir ;; + -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ + | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) + localstatedir=$ac_optarg ;; + + -mandir | --mandir | --mandi | --mand | --man | --ma | --m) + ac_prev=mandir ;; + -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) + mandir=$ac_optarg ;; + + -nfp | --nfp | --nf) + # Obsolete; use --without-fp. + with_fp=no ;; + + -no-create | --no-create | --no-creat | --no-crea | --no-cre \ + | --no-cr | --no-c | -n) + no_create=yes ;; + + -no-recursion | --no-recursion | --no-recursio | --no-recursi \ + | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) + no_recursion=yes ;; + + -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ + | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ + | --oldin | --oldi | --old | --ol | --o) + ac_prev=oldincludedir ;; + -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ + | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ + | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) + oldincludedir=$ac_optarg ;; + + -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) + ac_prev=prefix ;; + -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) + prefix=$ac_optarg ;; + + -program-prefix | --program-prefix | --program-prefi | --program-pref \ + | --program-pre | --program-pr | --program-p) + ac_prev=program_prefix ;; + -program-prefix=* | --program-prefix=* | --program-prefi=* \ + | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) + program_prefix=$ac_optarg ;; + + -program-suffix | --program-suffix | --program-suffi | --program-suff \ + | --program-suf | --program-su | --program-s) + ac_prev=program_suffix ;; + -program-suffix=* | --program-suffix=* | --program-suffi=* \ + | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) + program_suffix=$ac_optarg ;; + + -program-transform-name | --program-transform-name \ + | --program-transform-nam | --program-transform-na \ + | --program-transform-n | --program-transform- \ + | --program-transform | --program-transfor \ + | --program-transfo | --program-transf \ + | --program-trans | --program-tran \ + | --progr-tra | --program-tr | --program-t) + ac_prev=program_transform_name ;; + -program-transform-name=* | --program-transform-name=* \ + | --program-transform-nam=* | --program-transform-na=* \ + | --program-transform-n=* | --program-transform-=* \ + | --program-transform=* | --program-transfor=* \ + | --program-transfo=* | --program-transf=* \ + | --program-trans=* | --program-tran=* \ + | --progr-tra=* | --program-tr=* | --program-t=*) + program_transform_name=$ac_optarg ;; + + -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) + ac_prev=pdfdir ;; + -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) + pdfdir=$ac_optarg ;; + + -psdir | --psdir | --psdi | --psd | --ps) + ac_prev=psdir ;; + -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) + psdir=$ac_optarg ;; + + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + silent=yes ;; + + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) + ac_prev=sbindir ;; + -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ + | --sbi=* | --sb=*) + sbindir=$ac_optarg ;; + + -sharedstatedir | --sharedstatedir | --sharedstatedi \ + | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ + | --sharedst | --shareds | --shared | --share | --shar \ + | --sha | --sh) + ac_prev=sharedstatedir ;; + -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ + | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ + | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ + | --sha=* | --sh=*) + sharedstatedir=$ac_optarg ;; + + -site | --site | --sit) + ac_prev=site ;; + -site=* | --site=* | --sit=*) + site=$ac_optarg ;; + + -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) + ac_prev=srcdir ;; + -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) + srcdir=$ac_optarg ;; + + -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ + | --syscon | --sysco | --sysc | --sys | --sy) + ac_prev=sysconfdir ;; + -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ + | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) + sysconfdir=$ac_optarg ;; + + -target | --target | --targe | --targ | --tar | --ta | --t) + ac_prev=target_alias ;; + -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) + target_alias=$ac_optarg ;; + + -v | -verbose | --verbose | --verbos | --verbo | --verb) + verbose=yes ;; + + -version | --version | --versio | --versi | --vers | -V) + ac_init_version=: ;; + + -with-* | --with-*) + ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=\$ac_optarg ;; + + -without-* | --without-*) + ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` + # Reject names that are not valid shell variable names. + expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid package name: $ac_package" >&2 + { (exit 1); exit 1; }; } + ac_package=`echo $ac_package | sed 's/[-.]/_/g'` + eval with_$ac_package=no ;; + + --x) + # Obsolete; use --with-x. + with_x=yes ;; + + -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ + | --x-incl | --x-inc | --x-in | --x-i) + ac_prev=x_includes ;; + -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ + | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) + x_includes=$ac_optarg ;; + + -x-libraries | --x-libraries | --x-librarie | --x-librari \ + | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) + ac_prev=x_libraries ;; + -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ + | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) + x_libraries=$ac_optarg ;; + + -*) { echo "$as_me: error: unrecognized option: $ac_option +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } + ;; + + *=*) + ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` + # Reject names that are not valid shell variable names. + expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && + { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 + { (exit 1); exit 1; }; } + eval $ac_envvar=\$ac_optarg + export $ac_envvar ;; + + *) + # FIXME: should be removed in autoconf 3.0. + echo "$as_me: WARNING: you should use --build, --host, --target" >&2 + expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && + echo "$as_me: WARNING: invalid host type: $ac_option" >&2 + : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} + ;; + + esac +done + +if test -n "$ac_prev"; then + ac_option=--`echo $ac_prev | sed 's/_/-/g'` + { echo "$as_me: error: missing argument to $ac_option" >&2 + { (exit 1); exit 1; }; } +fi + +# Be sure to have absolute directory names. +for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ + datadir sysconfdir sharedstatedir localstatedir includedir \ + oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ + libdir localedir mandir +do + eval ac_val=\$$ac_var + case $ac_val in + [\\/$]* | ?:[\\/]* ) continue;; + NONE | '' ) case $ac_var in *prefix ) continue;; esac;; + esac + { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 + { (exit 1); exit 1; }; } +done + +# There might be people who depend on the old broken behavior: `$host' +# used to hold the argument of --host etc. +# FIXME: To remove some day. +build=$build_alias +host=$host_alias +target=$target_alias + +# FIXME: To remove some day. +if test "x$host_alias" != x; then + if test "x$build_alias" = x; then + cross_compiling=maybe + echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. + If a cross compiler is detected then cross compile mode will be used." >&2 + elif test "x$build_alias" != "x$host_alias"; then + cross_compiling=yes + fi +fi + +ac_tool_prefix= +test -n "$host_alias" && ac_tool_prefix=$host_alias- + +test "$silent" = yes && exec 6>/dev/null + + +ac_pwd=`pwd` && test -n "$ac_pwd" && +ac_ls_di=`ls -di .` && +ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || + { echo "$as_me: error: Working directory cannot be determined" >&2 + { (exit 1); exit 1; }; } +test "X$ac_ls_di" = "X$ac_pwd_ls_di" || + { echo "$as_me: error: pwd does not report name of working directory" >&2 + { (exit 1); exit 1; }; } + + +# Find the source files, if location was not specified. +if test -z "$srcdir"; then + ac_srcdir_defaulted=yes + # Try the directory containing this script, then the parent directory. + ac_confdir=`$as_dirname -- "$0" || +$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X"$0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + srcdir=$ac_confdir + if test ! -r "$srcdir/$ac_unique_file"; then + srcdir=.. + fi +else + ac_srcdir_defaulted=no +fi +if test ! -r "$srcdir/$ac_unique_file"; then + test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." + { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 + { (exit 1); exit 1; }; } +fi +ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" +ac_abs_confdir=`( + cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 + { (exit 1); exit 1; }; } + pwd)` +# When building in place, set srcdir=. +if test "$ac_abs_confdir" = "$ac_pwd"; then + srcdir=. +fi +# Remove unnecessary trailing slashes from srcdir. +# Double slashes in file names in object file debugging info +# mess up M-x gdb in Emacs. +case $srcdir in +*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; +esac +for ac_var in $ac_precious_vars; do + eval ac_env_${ac_var}_set=\${${ac_var}+set} + eval ac_env_${ac_var}_value=\$${ac_var} + eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} + eval ac_cv_env_${ac_var}_value=\$${ac_var} +done + +# +# Report the --help message. +# +if test "$ac_init_help" = "long"; then + # Omit some internal or obsolete options to make the list less imposing. + # This message is too long to be a string in the A/UX 3.1 sh. + cat <<_ACEOF +\`configure' configures this package to adapt to many kinds of systems. + +Usage: $0 [OPTION]... [VAR=VALUE]... + +To assign environment variables (e.g., CC, CFLAGS...), specify them as +VAR=VALUE. See below for descriptions of some of the useful variables. + +Defaults for the options are specified in brackets. + +Configuration: + -h, --help display this help and exit + --help=short display options specific to this package + --help=recursive display the short help of all the included packages + -V, --version display version information and exit + -q, --quiet, --silent do not print \`checking...' messages + --cache-file=FILE cache test results in FILE [disabled] + -C, --config-cache alias for \`--cache-file=config.cache' + -n, --no-create do not create output files + --srcdir=DIR find the sources in DIR [configure dir or \`..'] + +Installation directories: + --prefix=PREFIX install architecture-independent files in PREFIX + [$ac_default_prefix] + --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX + [PREFIX] + +By default, \`make install' will install all the files in +\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify +an installation prefix other than \`$ac_default_prefix' using \`--prefix', +for instance \`--prefix=\$HOME'. + +For better control, use the options below. + +Fine tuning of the installation directories: + --bindir=DIR user executables [EPREFIX/bin] + --sbindir=DIR system admin executables [EPREFIX/sbin] + --libexecdir=DIR program executables [EPREFIX/libexec] + --sysconfdir=DIR read-only single-machine data [PREFIX/etc] + --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] + --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --libdir=DIR object code libraries [EPREFIX/lib] + --includedir=DIR C header files [PREFIX/include] + --oldincludedir=DIR C header files for non-gcc [/usr/include] + --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] + --datadir=DIR read-only architecture-independent data [DATAROOTDIR] + --infodir=DIR info documentation [DATAROOTDIR/info] + --localedir=DIR locale-dependent data [DATAROOTDIR/locale] + --mandir=DIR man documentation [DATAROOTDIR/man] + --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] + --htmldir=DIR html documentation [DOCDIR] + --dvidir=DIR dvi documentation [DOCDIR] + --pdfdir=DIR pdf documentation [DOCDIR] + --psdir=DIR ps documentation [DOCDIR] +_ACEOF + + cat <<\_ACEOF +_ACEOF +fi + +if test -n "$ac_init_help"; then + + cat <<\_ACEOF + +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-perl-prefix Location of Perl + +_ACEOF +ac_status=$? +fi + +if test "$ac_init_help" = "recursive"; then + # If there are subdirs, report their specific --help. + for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue + test -d "$ac_dir" || continue + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + cd "$ac_dir" || { ac_status=$?; continue; } + # Check for guested configure. + if test -f "$ac_srcdir/configure.gnu"; then + echo && + $SHELL "$ac_srcdir/configure.gnu" --help=recursive + elif test -f "$ac_srcdir/configure"; then + echo && + $SHELL "$ac_srcdir/configure" --help=recursive + else + echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 + fi || ac_status=$? + cd "$ac_pwd" || { ac_status=$?; break; } + done +fi + +test -n "$ac_init_help" && exit $ac_status +if $ac_init_version; then + cat <<\_ACEOF +configure +generated by GNU Autoconf 2.61 + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, +2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. +This configure script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it. +_ACEOF + exit +fi +cat >config.log <<_ACEOF +This file contains any messages produced by compilers while +running configure, to aid debugging if configure makes a mistake. + +It was created by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + $ $0 $@ + +_ACEOF +exec 5>>config.log +{ +cat <<_ASUNAME +## --------- ## +## Platform. ## +## --------- ## + +hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` + +/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` +/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` +/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` +/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` + +_ASUNAME + +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + echo "PATH: $as_dir" +done +IFS=$as_save_IFS + +} >&5 + +cat >&5 <<_ACEOF + + +## ----------- ## +## Core tests. ## +## ----------- ## + +_ACEOF + + +# Keep a trace of the command line. +# Strip out --no-create and --no-recursion so they do not pile up. +# Strip out --silent because we don't want to record it for future runs. +# Also quote any args containing shell meta-characters. +# Make two passes to allow for proper duplicate-argument suppression. +ac_configure_args= +ac_configure_args0= +ac_configure_args1= +ac_must_keep_next=false +for ac_pass in 1 2 +do + for ac_arg + do + case $ac_arg in + -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil) + continue ;; + *\'*) + ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; + esac + case $ac_pass in + 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; + 2) + ac_configure_args1="$ac_configure_args1 '$ac_arg'" + if test $ac_must_keep_next = true; then + ac_must_keep_next=false # Got value, back to normal. + else + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac + fi + ac_configure_args="$ac_configure_args '$ac_arg'" + ;; + esac + done +done +$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } +$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } + +# When interrupted or exit'd, cleanup temporary files, and complete +# config.log. We remove comments because anyway the quotes in there +# would cause problems or look ugly. +# WARNING: Use '\'' to represent an apostrophe within the trap. +# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. +trap 'exit_status=$? + # Save into config.log some information that might help in debugging. + { + echo + + cat <<\_ASBOX +## ---------------- ## +## Cache variables. ## +## ---------------- ## +_ASBOX + echo + # The following way of writing the cache mishandles newlines in values, +( + for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + (set) 2>&1 | + case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + sed -n \ + "s/'\''/'\''\\\\'\'''\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" + ;; #( + *) + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) + echo + + cat <<\_ASBOX +## ----------------- ## +## Output variables. ## +## ----------------- ## +_ASBOX + echo + for ac_var in $ac_subst_vars + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + + if test -n "$ac_subst_files"; then + cat <<\_ASBOX +## ------------------- ## +## File substitutions. ## +## ------------------- ## +_ASBOX + echo + for ac_var in $ac_subst_files + do + eval ac_val=\$$ac_var + case $ac_val in + *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; + esac + echo "$ac_var='\''$ac_val'\''" + done | sort + echo + fi + + if test -s confdefs.h; then + cat <<\_ASBOX +## ----------- ## +## confdefs.h. ## +## ----------- ## +_ASBOX + echo + cat confdefs.h + echo + fi + test "$ac_signal" != 0 && + echo "$as_me: caught signal $ac_signal" + echo "$as_me: exit $exit_status" + } >&5 + rm -f core *.core core.conftest.* && + rm -f -r conftest* confdefs* conf$$* $ac_clean_files && + exit $exit_status +' 0 +for ac_signal in 1 2 13 15; do + trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal +done +ac_signal=0 + +# confdefs.h avoids OS command line length limits that DEFS can exceed. +rm -f -r conftest* confdefs.h + +# Predefined preprocessor variables. + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_NAME "$PACKAGE_NAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_TARNAME "$PACKAGE_TARNAME" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_VERSION "$PACKAGE_VERSION" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_STRING "$PACKAGE_STRING" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" +_ACEOF + + +# Let the site file select an alternate cache file if it wants to. +# Prefer explicitly selected file to automatically selected ones. +if test -n "$CONFIG_SITE"; then + set x "$CONFIG_SITE" +elif test "x$prefix" != xNONE; then + set x "$prefix/share/config.site" "$prefix/etc/config.site" +else + set x "$ac_default_prefix/share/config.site" \ + "$ac_default_prefix/etc/config.site" +fi +shift +for ac_site_file +do + if test -r "$ac_site_file"; then + { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 +echo "$as_me: loading site script $ac_site_file" >&6;} + sed 's/^/| /' "$ac_site_file" >&5 + . "$ac_site_file" + fi +done + +if test -r "$cache_file"; then + # Some versions of bash will fail to source /dev/null (special + # files actually), so we avoid doing that. + if test -f "$cache_file"; then + { echo "$as_me:$LINENO: loading cache $cache_file" >&5 +echo "$as_me: loading cache $cache_file" >&6;} + case $cache_file in + [\\/]* | ?:[\\/]* ) . "$cache_file";; + *) . "./$cache_file";; + esac + fi +else + { echo "$as_me:$LINENO: creating cache $cache_file" >&5 +echo "$as_me: creating cache $cache_file" >&6;} + >$cache_file +fi + +# Check that the precious variables saved in the cache have kept the same +# value. +ac_cache_corrupted=false +for ac_var in $ac_precious_vars; do + eval ac_old_set=\$ac_cv_env_${ac_var}_set + eval ac_new_set=\$ac_env_${ac_var}_set + eval ac_old_val=\$ac_cv_env_${ac_var}_value + eval ac_new_val=\$ac_env_${ac_var}_value + case $ac_old_set,$ac_new_set in + set,) + { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,set) + { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 +echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} + ac_cache_corrupted=: ;; + ,);; + *) + if test "x$ac_old_val" != "x$ac_new_val"; then + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 +echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 +echo "$as_me: former value: $ac_old_val" >&2;} + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 +echo "$as_me: current value: $ac_new_val" >&2;} + ac_cache_corrupted=: + fi;; + esac + # Pass precious variables to config.status. + if test "$ac_new_set" = set; then + case $ac_new_val in + *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; + *) ac_arg=$ac_var=$ac_new_val ;; + esac + case " $ac_configure_args " in + *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. + *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; + esac + fi +done +if $ac_cache_corrupted; then + { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 +echo "$as_me: error: changes in the environment can compromise the build" >&2;} + { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 +echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} + { (exit 1); exit 1; }; } +fi + + + + + + + + + + + + + + + + + +ac_ext=c +ac_cpp='$CPP $CPPFLAGS' +ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' +ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' +ac_compiler_gnu=$ac_cv_c_compiler_gnu + + + + +# Programs +ac_aux_dir= +for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do + if test -f "$ac_dir/install-sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install-sh -c" + break + elif test -f "$ac_dir/install.sh"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/install.sh -c" + break + elif test -f "$ac_dir/shtool"; then + ac_aux_dir=$ac_dir + ac_install_sh="$ac_aux_dir/shtool install -c" + break + fi +done +if test -z "$ac_aux_dir"; then + { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 +echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} + { (exit 1); exit 1; }; } +fi + +# These three variables are undocumented and unsupported, +# and are intended to be withdrawn in a future Autoconf release. +# They can cause serious problems if a builder's source tree is in a directory +# whose full name contains unusual characters. +ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. +ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. +ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. + + +# Find a good install program. We prefer a C program (faster), +# so one script is as good as another. But avoid the broken or +# incompatible versions: +# SysV /etc/install, /usr/sbin/install +# SunOS /usr/etc/install +# IRIX /sbin/install +# AIX /bin/install +# AmigaOS /C/install, which installs bootblocks on floppy discs +# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag +# AFS /usr/afsws/bin/install, which mishandles nonexistent args +# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic +# ./install, which can be erroneously created by make from ./install.sh. +{ echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 +echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } +if test -z "$INSTALL"; then +if test "${ac_cv_path_install+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + # Account for people who put trailing slashes in PATH elements. +case $as_dir/ in + ./ | .// | /cC/* | \ + /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ + /usr/ucb/* ) ;; + *) + # OSF1 and SCO ODT 3.0 have their own names for install. + # Don't use installbsd from OSF since it installs stuff as root + # by default. + for ac_prog in ginstall scoinst install; do + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi + done + done + ;; +esac +done +IFS=$as_save_IFS + + +fi + if test "${ac_cv_path_install+set}" = set; then + INSTALL=$ac_cv_path_install + else + # As a last resort, use the slow shell script. Don't cache a + # value for INSTALL within a source directory, because that will + # break other packages using the cache if that directory is + # removed, or if the value is a relative name. + INSTALL=$ac_install_sh + fi +fi +{ echo "$as_me:$LINENO: result: $INSTALL" >&5 +echo "${ECHO_T}$INSTALL" >&6; } + +# Use test -z because SunOS4 sh mishandles braces in ${var-val}. +# It thinks the first close brace ends the variable substitution. +test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' + +test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' + +test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' + + +for ac_prog in sed +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_SED+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $SED in + [\\/]* | ?:[\\/]*) + ac_cv_path_SED="$SED" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/bin:/usr/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_SED="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +SED=$ac_cv_path_SED +if test -n "$SED"; then + { echo "$as_me:$LINENO: result: $SED" >&5 +echo "${ECHO_T}$SED" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$SED" && break +done + + +# Check for Perl + +# Check whether --with-perl-prefix was given. +if test "${with_perl_prefix+set}" = set; then + withval=$with_perl_prefix; PERLPATH=$withval +else + PERLPATH="" +fi + + +if ( test -n "$PERLPATH" -a "`echo $PERLPATH | cut -c-3`" = "../" ); then + PERLPATH="$PWD/$PERLPATH" +fi + +PERL="" +if ( test -n "$PERLPATH" ); then + as_ac_File=`echo "ac_cv_file_"$PERLPATH/bin/perl"" | $as_tr_sh` +{ echo "$as_me:$LINENO: checking for \"$PERLPATH/bin/perl\"" >&5 +echo $ECHO_N "checking for \"$PERLPATH/bin/perl\"... $ECHO_C" >&6; } +if { as_var=$as_ac_File; eval "test \"\${$as_var+set}\" = set"; }; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + test "$cross_compiling" = yes && + { { echo "$as_me:$LINENO: error: cannot check for file existence when cross compiling" >&5 +echo "$as_me: error: cannot check for file existence when cross compiling" >&2;} + { (exit 1); exit 1; }; } +if test -r ""$PERLPATH/bin/perl""; then + eval "$as_ac_File=yes" +else + eval "$as_ac_File=no" +fi +fi +ac_res=`eval echo '${'$as_ac_File'}'` + { echo "$as_me:$LINENO: result: $ac_res" >&5 +echo "${ECHO_T}$ac_res" >&6; } +if test `eval echo '${'$as_ac_File'}'` = yes; then + PERL="$PERLPATH/bin/perl" +fi + +else + for ac_prog in perl +do + # Extract the first word of "$ac_prog", so it can be a program name with args. +set dummy $ac_prog; ac_word=$2 +{ echo "$as_me:$LINENO: checking for $ac_word" >&5 +echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } +if test "${ac_cv_path_PERL+set}" = set; then + echo $ECHO_N "(cached) $ECHO_C" >&6 +else + case $PERL in + [\\/]* | ?:[\\/]*) + ac_cv_path_PERL="$PERL" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +as_dummy="$PATH:/usr/bin:/usr/local/bin:/usr/pkg/bin:/usr/local/perl/bin:/opt/sfw/bin" +for as_dir in $as_dummy +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then + ac_cv_path_PERL="$as_dir/$ac_word$ac_exec_ext" + echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done +done +IFS=$as_save_IFS + + ;; +esac +fi +PERL=$ac_cv_path_PERL +if test -n "$PERL"; then + { echo "$as_me:$LINENO: result: $PERL" >&5 +echo "${ECHO_T}$PERL" >&6; } +else + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } +fi + + + test -n "$PERL" && break +done + +fi +if ( test -z "$PERL" ); then + { { echo "$as_me:$LINENO: error: \"Perl is required\"" >&5 +echo "$as_me: error: \"Perl is required\"" >&2;} + { (exit 1); exit 1; }; } +fi + + + +# Check that Perl Libraries are available: +# DBI +# DBD::Pg +# Fcntl +# HTML::Template +# Term::ReadKey +# +# Output of if test redirected to /dev/null to keep quiet +for module in DBI DBD::Pg Fcntl HTML::Template Term::ReadKey ; do + { echo "$as_me:$LINENO: checking ${module}" >&5 +echo $ECHO_N "checking ${module}... $ECHO_C" >&6; } + if ! (${PERL} -e "use ${module}" 2>&1 /dev/null ) ; then + { echo "$as_me:$LINENO: result: no" >&5 +echo "${ECHO_T}no" >&6; } + { { echo "$as_me:$LINENO: error: Perl module ${module} is required" >&5 +echo "$as_me: error: Perl module ${module} is required" >&2;} + { (exit 1); exit 1; }; } + else + { echo "$as_me:$LINENO: result: yes" >&5 +echo "${ECHO_T}yes" >&6; } + fi +done + + +ac_config_files="$ac_config_files config.mk" + +cat >confcache <<\_ACEOF +# This file is a shell script that caches the results of configure +# tests run on this system so they can be shared between configure +# scripts and configure runs, see configure's option --config-cache. +# It is not useful on other systems. If it contains results you don't +# want to keep, you may remove or edit it. +# +# config.status only pays attention to the cache file if you give it +# the --recheck option to rerun configure. +# +# `ac_cv_env_foo' variables (set or unset) will be overridden when +# loading this file, other *unset* `ac_cv_foo' will be assigned the +# following values. + +_ACEOF + +# The following way of writing the cache mishandles newlines in values, +# but we know of no workaround that is simple, portable, and efficient. +# So, we kill variables containing newlines. +# Ultrix sh set writes to stderr and can't be redirected directly, +# and sets the high bit in the cache file unless we assign to the vars. +( + for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do + eval ac_val=\$$ac_var + case $ac_val in #( + *${as_nl}*) + case $ac_var in #( + *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 +echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; + esac + case $ac_var in #( + _ | IFS | as_nl) ;; #( + *) $as_unset $ac_var ;; + esac ;; + esac + done + + (set) 2>&1 | + case $as_nl`(ac_space=' '; set) 2>&1` in #( + *${as_nl}ac_space=\ *) + # `set' does not quote correctly, so add quotes (double-quote + # substitution turns \\\\ into \\, and sed turns \\ into \). + sed -n \ + "s/'/'\\\\''/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" + ;; #( + *) + # `set' quotes correctly as required by POSIX, so do not add quotes. + sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" + ;; + esac | + sort +) | + sed ' + /^ac_cv_env_/b end + t clear + :clear + s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ + t end + s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ + :end' >>confcache +if diff "$cache_file" confcache >/dev/null 2>&1; then :; else + if test -w "$cache_file"; then + test "x$cache_file" != "x/dev/null" && + { echo "$as_me:$LINENO: updating cache $cache_file" >&5 +echo "$as_me: updating cache $cache_file" >&6;} + cat confcache >$cache_file + else + { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 +echo "$as_me: not updating unwritable cache $cache_file" >&6;} + fi +fi +rm -f confcache + +test "x$prefix" = xNONE && prefix=$ac_default_prefix +# Let make expand exec_prefix. +test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' + +# Transform confdefs.h into DEFS. +# Protect against shell expansion while executing Makefile rules. +# Protect against Makefile macro expansion. +# +# If the first sed substitution is executed (which looks for macros that +# take arguments), then branch to the quote section. Otherwise, +# look for a macro that doesn't take arguments. +ac_script=' +t clear +:clear +s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g +t quote +s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g +t quote +b any +:quote +s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g +s/\[/\\&/g +s/\]/\\&/g +s/\$/$$/g +H +:any +${ + g + s/^\n// + s/\n/ /g + p +} +' +DEFS=`sed -n "$ac_script" confdefs.h` + + +ac_libobjs= +ac_ltlibobjs= +for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue + # 1. Remove the extension, and $U if already installed. + ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' + ac_i=`echo "$ac_i" | sed "$ac_script"` + # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR + # will be set to the directory where LIBOBJS objects are built. + ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" + ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' +done +LIBOBJS=$ac_libobjs + +LTLIBOBJS=$ac_ltlibobjs + + + +: ${CONFIG_STATUS=./config.status} +ac_clean_files_save=$ac_clean_files +ac_clean_files="$ac_clean_files $CONFIG_STATUS" +{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 +echo "$as_me: creating $CONFIG_STATUS" >&6;} +cat >$CONFIG_STATUS <<_ACEOF +#! $SHELL +# Generated by $as_me. +# Run this file to recreate the current configuration. +# Compiler output produced by configure, useful for debugging +# configure, is in config.log if it exists. + +debug=false +ac_cs_recheck=false +ac_cs_silent=false +SHELL=\${CONFIG_SHELL-$SHELL} +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +## --------------------- ## +## M4sh Initialization. ## +## --------------------- ## + +# Be more Bourne compatible +DUALCASE=1; export DUALCASE # for MKS sh +if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then + emulate sh + NULLCMD=: + # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which + # is contrary to our usage. Disable this feature. + alias -g '${1+"$@"}'='"$@"' + setopt NO_GLOB_SUBST +else + case `(set -o) 2>/dev/null` in + *posix*) set -o posix ;; +esac + +fi + + + + +# PATH needs CR +# Avoid depending upon Character Ranges. +as_cr_letters='abcdefghijklmnopqrstuvwxyz' +as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' +as_cr_Letters=$as_cr_letters$as_cr_LETTERS +as_cr_digits='0123456789' +as_cr_alnum=$as_cr_Letters$as_cr_digits + +# The user is always right. +if test "${PATH_SEPARATOR+set}" != set; then + echo "#! /bin/sh" >conf$$.sh + echo "exit 0" >>conf$$.sh + chmod +x conf$$.sh + if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then + PATH_SEPARATOR=';' + else + PATH_SEPARATOR=: + fi + rm -f conf$$.sh +fi + +# Support unset when possible. +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then + as_unset=unset +else + as_unset=false +fi + + +# IFS +# We need space, tab and new line, in precisely that order. Quoting is +# there to prevent editors from complaining about space-tab. +# (If _AS_PATH_WALK were called with IFS unset, it would disable word +# splitting by setting IFS to empty value.) +as_nl=' +' +IFS=" "" $as_nl" + +# Find who we are. Look in the path if we contain no directory separator. +case $0 in + *[\\/]* ) as_myself=$0 ;; + *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break +done +IFS=$as_save_IFS + + ;; +esac +# We did not find ourselves, most probably we were run as `sh COMMAND' +# in which case we are not to be found in the path. +if test "x$as_myself" = x; then + as_myself=$0 +fi +if test ! -f "$as_myself"; then + echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 + { (exit 1); exit 1; } +fi + +# Work around bugs in pre-3.0 UWIN ksh. +for as_var in ENV MAIL MAILPATH +do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var +done +PS1='$ ' +PS2='> ' +PS4='+ ' + +# NLS nuisances. +for as_var in \ + LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ + LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ + LC_TELEPHONE LC_TIME +do + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then + eval $as_var=C; export $as_var + else + ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var + fi +done + +# Required to use basename. +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then + as_basename=basename +else + as_basename=false +fi + + +# Name of the executable. +as_me=`$as_basename -- "$0" || +$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| . 2>/dev/null || +echo X/"$0" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ + s//\1/ + q + } + /^X\/\(\/\/\)$/{ + s//\1/ + q + } + /^X\/\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + +# CDPATH. +$as_unset CDPATH + + + + as_lineno_1=$LINENO + as_lineno_2=$LINENO + test "x$as_lineno_1" != "x$as_lineno_2" && + test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { + + # Create $as_me.lineno as a copy of $as_myself, but with $LINENO + # uniformly replaced by the line number. The first 'sed' inserts a + # line-number line after each line using $LINENO; the second 'sed' + # does the real work. The second script uses 'N' to pair each + # line-number line with the line containing $LINENO, and appends + # trailing '-' during substitution so that $LINENO is not a special + # case at line end. + # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the + # scripts with optimization help from Paolo Bonzini. Blame Lee + # E. McMahon (1931-1989) for sed's syntax. :-) + sed -n ' + p + /[$]LINENO/= + ' <$as_myself | + sed ' + s/[$]LINENO.*/&-/ + t lineno + b + :lineno + N + :loop + s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ + t loop + s/-\n.*// + ' >$as_me.lineno && + chmod +x "$as_me.lineno" || + { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 + { (exit 1); exit 1; }; } + + # Don't try to exec as it changes $[0], causing all sort of problems + # (the dirname of $[0] is not the place where we might find the + # original and so on. Autoconf is especially sensitive to this). + . "./$as_me.lineno" + # Exit status is that of the last command. + exit +} + + +if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then + as_dirname=dirname +else + as_dirname=false +fi + +ECHO_C= ECHO_N= ECHO_T= +case `echo -n x` in +-n*) + case `echo 'x\c'` in + *c*) ECHO_T=' ';; # ECHO_T is single tab character. + *) ECHO_C='\c';; + esac;; +*) + ECHO_N='-n';; +esac + +if expr a : '\(a\)' >/dev/null 2>&1 && + test "X`expr 00001 : '.*\(...\)'`" = X001; then + as_expr=expr +else + as_expr=false +fi + +rm -f conf$$ conf$$.exe conf$$.file +if test -d conf$$.dir; then + rm -f conf$$.dir/conf$$.file +else + rm -f conf$$.dir + mkdir conf$$.dir +fi +echo >conf$$.file +if ln -s conf$$.file conf$$ 2>/dev/null; then + as_ln_s='ln -s' + # ... but there are two gotchas: + # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. + # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. + # In both cases, we have to default to `cp -p'. + ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || + as_ln_s='cp -p' +elif ln conf$$.file conf$$ 2>/dev/null; then + as_ln_s=ln +else + as_ln_s='cp -p' +fi +rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file +rmdir conf$$.dir 2>/dev/null + +if mkdir -p . 2>/dev/null; then + as_mkdir_p=: +else + test -d ./-p && rmdir ./-p + as_mkdir_p=false +fi + +if test -x / >/dev/null 2>&1; then + as_test_x='test -x' +else + if ls -dL / >/dev/null 2>&1; then + as_ls_L_option=L + else + as_ls_L_option= + fi + as_test_x=' + eval sh -c '\'' + if test -d "$1"; then + test -d "$1/."; + else + case $1 in + -*)set "./$1";; + esac; + case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in + ???[sx]*):;;*)false;;esac;fi + '\'' sh + ' +fi +as_executable_p=$as_test_x + +# Sed expression to map a string onto a valid CPP name. +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" + +# Sed expression to map a string onto a valid variable name. +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" + + +exec 6>&1 + +# Save the log message, to keep $[0] and so on meaningful, and to +# report actual input values of CONFIG_FILES etc. instead of their +# values after options handling. +ac_log=" +This file was extended by $as_me, which was +generated by GNU Autoconf 2.61. Invocation command line was + + CONFIG_FILES = $CONFIG_FILES + CONFIG_HEADERS = $CONFIG_HEADERS + CONFIG_LINKS = $CONFIG_LINKS + CONFIG_COMMANDS = $CONFIG_COMMANDS + $ $0 $@ + +on `(hostname || uname -n) 2>/dev/null | sed 1q` +" + +_ACEOF + +cat >>$CONFIG_STATUS <<_ACEOF +# Files that config.status was made for. +config_files="$ac_config_files" + +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +ac_cs_usage="\ +\`$as_me' instantiates files from templates according to the +current configuration. + +Usage: $0 [OPTIONS] [FILE]... + + -h, --help print this help, then exit + -V, --version print version number and configuration settings, then exit + -q, --quiet do not print progress messages + -d, --debug don't remove temporary files + --recheck update $as_me by reconfiguring in the same conditions + --file=FILE[:TEMPLATE] + instantiate the configuration file FILE + +Configuration files: +$config_files + +Report bugs to <bug-autoconf@gnu.org>." + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +ac_cs_version="\\ +config.status +configured by $0, generated by GNU Autoconf 2.61, + with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" + +Copyright (C) 2006 Free Software Foundation, Inc. +This config.status script is free software; the Free Software Foundation +gives unlimited permission to copy, distribute and modify it." + +ac_pwd='$ac_pwd' +srcdir='$srcdir' +INSTALL='$INSTALL' +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If no file are specified by the user, then we need to provide default +# value. By we need to know if files were specified by the user. +ac_need_defaults=: +while test $# != 0 +do + case $1 in + --*=*) + ac_option=`expr "X$1" : 'X\([^=]*\)='` + ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` + ac_shift=: + ;; + *) + ac_option=$1 + ac_optarg=$2 + ac_shift=shift + ;; + esac + + case $ac_option in + # Handling of the options. + -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) + ac_cs_recheck=: ;; + --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) + echo "$ac_cs_version"; exit ;; + --debug | --debu | --deb | --de | --d | -d ) + debug=: ;; + --file | --fil | --fi | --f ) + $ac_shift + CONFIG_FILES="$CONFIG_FILES $ac_optarg" + ac_need_defaults=false;; + --he | --h | --help | --hel | -h ) + echo "$ac_cs_usage"; exit ;; + -q | -quiet | --quiet | --quie | --qui | --qu | --q \ + | -silent | --silent | --silen | --sile | --sil | --si | --s) + ac_cs_silent=: ;; + + # This is an error. + -*) { echo "$as_me: error: unrecognized option: $1 +Try \`$0 --help' for more information." >&2 + { (exit 1); exit 1; }; } ;; + + *) ac_config_targets="$ac_config_targets $1" + ac_need_defaults=false ;; + + esac + shift +done + +ac_configure_extra_args= + +if $ac_cs_silent; then + exec 6>/dev/null + ac_configure_extra_args="$ac_configure_extra_args --silent" +fi + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +if \$ac_cs_recheck; then + echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 + CONFIG_SHELL=$SHELL + export CONFIG_SHELL + exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion +fi + +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +exec 5>>config.log +{ + echo + sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX +## Running $as_me. ## +_ASBOX + echo "$ac_log" +} >&5 + +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF + +# Handling of arguments. +for ac_config_target in $ac_config_targets +do + case $ac_config_target in + "config.mk") CONFIG_FILES="$CONFIG_FILES config.mk" ;; + + *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 +echo "$as_me: error: invalid argument: $ac_config_target" >&2;} + { (exit 1); exit 1; }; };; + esac +done + + +# If the user did not use the arguments to specify the items to instantiate, +# then the envvar interface is used. Set only those that are not. +# We use the long form for the default assignment because of an extremely +# bizarre bug on SunOS 4.1.3. +if $ac_need_defaults; then + test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files +fi + +# Have a temporary directory for convenience. Make it in the build tree +# simply because there is no reason against having it here, and in addition, +# creating and moving files from /tmp can sometimes cause problems. +# Hook for its removal unless debugging. +# Note that there is a small window in which the directory will not be cleaned: +# after its creation but before its name has been assigned to `$tmp'. +$debug || +{ + tmp= + trap 'exit_status=$? + { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status +' 0 + trap '{ (exit 1); exit 1; }' 1 2 13 15 +} +# Create a (secure) tmp directory for tmp files. + +{ + tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && + test -n "$tmp" && test -d "$tmp" +} || +{ + tmp=./conf$$-$RANDOM + (umask 077 && mkdir "$tmp") +} || +{ + echo "$me: cannot create a temporary directory in ." >&2 + { (exit 1); exit 1; } +} + +# +# Set up the sed scripts for CONFIG_FILES section. +# + +# No need to generate the scripts if there are no CONFIG_FILES. +# This happens for instance when ./config.status config.h +if test -n "$CONFIG_FILES"; then + +_ACEOF + + + +ac_delim='%!_!# ' +for ac_last_try in false false false false false :; do + cat >conf$$subs.sed <<_ACEOF +SHELL!$SHELL$ac_delim +PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim +PACKAGE_NAME!$PACKAGE_NAME$ac_delim +PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim +PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim +PACKAGE_STRING!$PACKAGE_STRING$ac_delim +PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim +exec_prefix!$exec_prefix$ac_delim +prefix!$prefix$ac_delim +program_transform_name!$program_transform_name$ac_delim +bindir!$bindir$ac_delim +sbindir!$sbindir$ac_delim +libexecdir!$libexecdir$ac_delim +datarootdir!$datarootdir$ac_delim +datadir!$datadir$ac_delim +sysconfdir!$sysconfdir$ac_delim +sharedstatedir!$sharedstatedir$ac_delim +localstatedir!$localstatedir$ac_delim +includedir!$includedir$ac_delim +oldincludedir!$oldincludedir$ac_delim +docdir!$docdir$ac_delim +infodir!$infodir$ac_delim +htmldir!$htmldir$ac_delim +dvidir!$dvidir$ac_delim +pdfdir!$pdfdir$ac_delim +psdir!$psdir$ac_delim +libdir!$libdir$ac_delim +localedir!$localedir$ac_delim +mandir!$mandir$ac_delim +DEFS!$DEFS$ac_delim +ECHO_C!$ECHO_C$ac_delim +ECHO_N!$ECHO_N$ac_delim +ECHO_T!$ECHO_T$ac_delim +LIBS!$LIBS$ac_delim +build_alias!$build_alias$ac_delim +host_alias!$host_alias$ac_delim +target_alias!$target_alias$ac_delim +INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim +INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim +INSTALL_DATA!$INSTALL_DATA$ac_delim +SED!$SED$ac_delim +PERL!$PERL$ac_delim +LIBOBJS!$LIBOBJS$ac_delim +LTLIBOBJS!$LTLIBOBJS$ac_delim +_ACEOF + + if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 44; then + break + elif $ac_last_try; then + { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 +echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} + { (exit 1); exit 1; }; } + else + ac_delim="$ac_delim!$ac_delim _$ac_delim!! " + fi +done + +ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` +if test -n "$ac_eof"; then + ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` + ac_eof=`expr $ac_eof + 1` +fi + +cat >>$CONFIG_STATUS <<_ACEOF +cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b end +_ACEOF +sed ' +s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g +s/^/s,@/; s/!/@,|#_!!_#|/ +:n +t n +s/'"$ac_delim"'$/,g/; t +s/$/\\/; p +N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n +' >>$CONFIG_STATUS <conf$$subs.sed +rm -f conf$$subs.sed +cat >>$CONFIG_STATUS <<_ACEOF +:end +s/|#_!!_#|//g +CEOF$ac_eof +_ACEOF + + +# VPATH may cause trouble with some makes, so we remove $(srcdir), +# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and +# trailing colons and then remove the whole line if VPATH becomes empty +# (actually we leave an empty line to preserve line numbers). +if test "x$srcdir" = x.; then + ac_vpsub='/^[ ]*VPATH[ ]*=/{ +s/:*\$(srcdir):*/:/ +s/:*\${srcdir}:*/:/ +s/:*@srcdir@:*/:/ +s/^\([^=]*=[ ]*\):*/\1/ +s/:*$// +s/^[^=]*=[ ]*$// +}' +fi + +cat >>$CONFIG_STATUS <<\_ACEOF +fi # test -n "$CONFIG_FILES" + + +for ac_tag in :F $CONFIG_FILES +do + case $ac_tag in + :[FHLC]) ac_mode=$ac_tag; continue;; + esac + case $ac_mode$ac_tag in + :[FHL]*:*);; + :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 +echo "$as_me: error: Invalid tag $ac_tag." >&2;} + { (exit 1); exit 1; }; };; + :[FH]-) ac_tag=-:-;; + :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; + esac + ac_save_IFS=$IFS + IFS=: + set x $ac_tag + IFS=$ac_save_IFS + shift + ac_file=$1 + shift + + case $ac_mode in + :L) ac_source=$1;; + :[FH]) + ac_file_inputs= + for ac_f + do + case $ac_f in + -) ac_f="$tmp/stdin";; + *) # Look for the file first in the build tree, then in the source tree + # (if the path is not absolute). The absolute path cannot be DOS-style, + # because $ac_f cannot contain `:'. + test -f "$ac_f" || + case $ac_f in + [\\/$]*) false;; + *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; + esac || + { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 +echo "$as_me: error: cannot find input file: $ac_f" >&2;} + { (exit 1); exit 1; }; };; + esac + ac_file_inputs="$ac_file_inputs $ac_f" + done + + # Let's still pretend it is `configure' which instantiates (i.e., don't + # use $as_me), people would be surprised to read: + # /* config.h. Generated by config.status. */ + configure_input="Generated from "`IFS=: + echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." + if test x"$ac_file" != x-; then + configure_input="$ac_file. $configure_input" + { echo "$as_me:$LINENO: creating $ac_file" >&5 +echo "$as_me: creating $ac_file" >&6;} + fi + + case $ac_tag in + *:-:* | *:-) cat >"$tmp/stdin";; + esac + ;; + esac + + ac_dir=`$as_dirname -- "$ac_file" || +$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$ac_file" : 'X\(//\)[^/]' \| \ + X"$ac_file" : 'X\(//\)$' \| \ + X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || +echo X"$ac_file" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + { as_dir="$ac_dir" + case $as_dir in #( + -*) as_dir=./$as_dir;; + esac + test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { + as_dirs= + while :; do + case $as_dir in #( + *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( + *) as_qdir=$as_dir;; + esac + as_dirs="'$as_qdir' $as_dirs" + as_dir=`$as_dirname -- "$as_dir" || +$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$as_dir" : 'X\(//\)[^/]' \| \ + X"$as_dir" : 'X\(//\)$' \| \ + X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || +echo X"$as_dir" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + test -d "$as_dir" && break + done + test -z "$as_dirs" || eval "mkdir $as_dirs" + } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 +echo "$as_me: error: cannot create directory $as_dir" >&2;} + { (exit 1); exit 1; }; }; } + ac_builddir=. + +case "$ac_dir" in +.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; +*) + ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` + # A ".." for each directory in $ac_dir_suffix. + ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` + case $ac_top_builddir_sub in + "") ac_top_builddir_sub=. ac_top_build_prefix= ;; + *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; + esac ;; +esac +ac_abs_top_builddir=$ac_pwd +ac_abs_builddir=$ac_pwd$ac_dir_suffix +# for backward compatibility: +ac_top_builddir=$ac_top_build_prefix + +case $srcdir in + .) # We are building in place. + ac_srcdir=. + ac_top_srcdir=$ac_top_builddir_sub + ac_abs_top_srcdir=$ac_pwd ;; + [\\/]* | ?:[\\/]* ) # Absolute name. + ac_srcdir=$srcdir$ac_dir_suffix; + ac_top_srcdir=$srcdir + ac_abs_top_srcdir=$srcdir ;; + *) # Relative name. + ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix + ac_top_srcdir=$ac_top_build_prefix$srcdir + ac_abs_top_srcdir=$ac_pwd/$srcdir ;; +esac +ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix + + + case $ac_mode in + :F) + # + # CONFIG_FILE + # + + case $INSTALL in + [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; + *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; + esac +_ACEOF + +cat >>$CONFIG_STATUS <<\_ACEOF +# If the template does not know about datarootdir, expand it. +# FIXME: This hack should be removed a few years after 2.60. +ac_datarootdir_hack=; ac_datarootdir_seen= + +case `sed -n '/datarootdir/ { + p + q +} +/@datadir@/p +/@docdir@/p +/@infodir@/p +/@localedir@/p +/@mandir@/p +' $ac_file_inputs` in +*datarootdir*) ac_datarootdir_seen=yes;; +*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) + { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 +echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} +_ACEOF +cat >>$CONFIG_STATUS <<_ACEOF + ac_datarootdir_hack=' + s&@datadir@&$datadir&g + s&@docdir@&$docdir&g + s&@infodir@&$infodir&g + s&@localedir@&$localedir&g + s&@mandir@&$mandir&g + s&\\\${datarootdir}&$datarootdir&g' ;; +esac +_ACEOF + +# Neutralize VPATH when `$srcdir' = `.'. +# Shell code in configure.ac might set extrasub. +# FIXME: do we really want to maintain this feature? +cat >>$CONFIG_STATUS <<_ACEOF + sed "$ac_vpsub +$extrasub +_ACEOF +cat >>$CONFIG_STATUS <<\_ACEOF +:t +/@[a-zA-Z_][a-zA-Z_0-9]*@/!b +s&@configure_input@&$configure_input&;t t +s&@top_builddir@&$ac_top_builddir_sub&;t t +s&@srcdir@&$ac_srcdir&;t t +s&@abs_srcdir@&$ac_abs_srcdir&;t t +s&@top_srcdir@&$ac_top_srcdir&;t t +s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t +s&@builddir@&$ac_builddir&;t t +s&@abs_builddir@&$ac_abs_builddir&;t t +s&@abs_top_builddir@&$ac_abs_top_builddir&;t t +s&@INSTALL@&$ac_INSTALL&;t t +$ac_datarootdir_hack +" $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out + +test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && + { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && + { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && + { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&5 +echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' +which seems to be undefined. Please make sure it is defined." >&2;} + + rm -f "$tmp/stdin" + case $ac_file in + -) cat "$tmp/out"; rm -f "$tmp/out";; + *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; + esac + ;; + + + + esac + +done # for ac_tag + + +{ (exit 0); exit 0; } +_ACEOF +chmod +x $CONFIG_STATUS +ac_clean_files=$ac_clean_files_save + + +# configure is writing to config.log, and then calls config.status. +# config.status does its own redirection, appending to config.log. +# Unfortunately, on DOS this fails, as config.log is still kept open +# by configure, so config.status won't be able to write to it; its +# output is simply discarded. So we exec the FD to /dev/null, +# effectively closing config.log, so it can be properly (re)opened and +# appended to by config.status. When coming back to configure, we +# need to make the FD available again. +if test "$no_create" != yes; then + ac_cs_success=: + ac_config_status_args= + test "$silent" = yes && + ac_config_status_args="$ac_config_status_args --quiet" + exec 5>/dev/null + $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false + exec 5>>config.log + # Use ||, not &&, to avoid exiting from the if with $? = 1, which + # would make configure fail if this is the last instruction. + $ac_cs_success || { (exit 1); exit 1; } +fi + diff --git a/postgresql_autodoc/configure.ac b/postgresql_autodoc/configure.ac new file mode 100644 index 0000000..128a044 --- /dev/null +++ b/postgresql_autodoc/configure.ac @@ -0,0 +1,56 @@ +AC_PREREQ(2.53) +AC_REVISION($Header: /cvsroot/autodoc/autodoc/configure.ac,v 1.2 2007/01/02 13:53:19 rbt Exp $) +AC_INIT(postgresql_autodoc.pl) + + +# Programs +AC_PROG_INSTALL + +AC_PATH_PROGS([SED], [sed], , + [$PATH:/bin:/usr/bin]) + +# Check for Perl +AC_ARG_WITH(perl-prefix, + [ --with-perl-prefix Location of Perl], + PERLPATH=$withval, + PERLPATH="") + +if ( test -n "$PERLPATH" -a "`echo $PERLPATH | cut -c-3`" = "../" ); then + PERLPATH="$PWD/$PERLPATH" +fi + +PERL="" +if ( test -n "$PERLPATH" ); then + AC_CHECK_FILE("$PERLPATH/bin/perl",PERL="$PERLPATH/bin/perl") +else + AC_PATH_PROGS([PERL], [perl], , + [$PATH:/usr/bin:/usr/local/bin:/usr/pkg/bin:/usr/local/perl/bin:/opt/sfw/bin]) +fi +if ( test -z "$PERL" ); then + AC_MSG_ERROR("Perl is required") +fi +AC_SUBST(PERL) + + +# Check that Perl Libraries are available: +# DBI +# DBD::Pg +# Fcntl +# HTML::Template +# Term::ReadKey +# +# Output of if test redirected to /dev/null to keep quiet +for module in DBI DBD::Pg Fcntl HTML::Template Term::ReadKey ; do + AC_MSG_CHECKING(${module}) + if [ ! (${PERL} -e "use ${module}" 2>&1 /dev/null ) ]; then + AC_MSG_RESULT(no) + AC_MSG_ERROR(Perl module ${module} is required) + else + AC_MSG_RESULT(yes) + fi +done + + +AC_OUTPUT([ +config.mk +]) diff --git a/postgresql_autodoc/dia.tmpl b/postgresql_autodoc/dia.tmpl new file mode 100644 index 0000000..88143e9 --- /dev/null +++ b/postgresql_autodoc/dia.tmpl @@ -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> diff --git a/postgresql_autodoc/dot.tmpl b/postgresql_autodoc/dot.tmpl new file mode 100644 index 0000000..1cb9ca6 --- /dev/null +++ b/postgresql_autodoc/dot.tmpl @@ -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"> +} diff --git a/postgresql_autodoc/html.tmpl b/postgresql_autodoc/html.tmpl new file mode 100644 index 0000000..4830b15 --- /dev/null +++ b/postgresql_autodoc/html.tmpl @@ -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> </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> </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> </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>♦</center><!-- /TMPL_IF name="select" --></td> + <td><!-- TMPL_IF name="insert" --><center>♦</center><!-- /TMPL_IF name="insert" --></td> + <td><!-- TMPL_IF name="update" --><center>♦</center><!-- /TMPL_IF name="update" --></td> + <td><!-- TMPL_IF name="delete" --><center>♦</center><!-- /TMPL_IF name="delete" --></td> + <td><!-- TMPL_IF name="references" --><center>♦</center><!-- /TMPL_IF name="references" --></td> + <td><!-- TMPL_IF name="rule" --><center>♦</center><!-- /TMPL_IF name="rule" --></td> + <td><!-- TMPL_IF name="trigger" --><center>♦</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> diff --git a/postgresql_autodoc/install-sh b/postgresql_autodoc/install-sh new file mode 100755 index 0000000..398a88e --- /dev/null +++ b/postgresql_autodoc/install-sh @@ -0,0 +1,251 @@ +#!/bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in supporting +# documentation, and that the name of M.I.T. not be used in advertising or +# publicity pertaining to distribution of the software without specific, +# written prior permission. M.I.T. makes no representations about the +# suitability of this software for any purpose. It is provided "as is" +# without express or implied warranty. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + : +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + chmodcmd="" + else + instcmd=$mkdirprog + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + : + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + : + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + : + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' + ' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + : + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + : + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/postgresql_autodoc/neato.tmpl b/postgresql_autodoc/neato.tmpl new file mode 100644 index 0000000..b21e067 --- /dev/null +++ b/postgresql_autodoc/neato.tmpl @@ -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"> +} + + diff --git a/postgresql_autodoc/postgresql_autodoc b/postgresql_autodoc/postgresql_autodoc new file mode 100755 index 0000000..503a8c5 --- /dev/null +++ b/postgresql_autodoc/postgresql_autodoc @@ -0,0 +1,1907 @@ +#!/usr/bin/perl +# -- # -*- Perl -*-w +# $Header: /cvsroot/autodoc/autodoc/postgresql_autodoc.pl,v 1.21 2008/03/12 19:00:56 rbt Exp $ +# Imported 1.22 2002/02/08 17:09:48 into sourceforge + +# Postgres Auto-Doc Version 1.31 + +# License +# ------- +# Copyright (c) 2001-2007, 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/local/share/postgresql_autodoc will be replaced by make in the build phase + my $template_path = '/usr/local/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 $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; + }; + + # 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, $statistics, $table_out ); + + # Write out *ALL* templates + write_using_templates( \%db, $database, $statistics, $template_path, + $output_filename_base, $wanted_output ); +} ## end sub main($) + +## +# info_collect +# +# Pull out all of the applicable information about a specific database +sub info_collect { + my ( $dbConnect, $db, $database, $only_schema, $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 . '$'; + } + + # + # 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 + , relhasindex as hasindexes + , relhasrules as hasrules + , reltriggers as hastriggers + , 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 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; + if ( $dbh->{pg_server_version} >= 70400 ) { + $sql_Constraint = q{ + SELECT pg_get_constraintdef(oid) AS constraint_source + , conname AS constraint_name + FROM pg_constraint + WHERE conrelid = ? + AND contype = 'c'; + }; + } + else { + $sql_Constraint = q{ + SELECT 'CHECK ' || pg_catalog.substr(consrc, 2, length(consrc) - 2) 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; + if ( $dbh->{pg_server_version} >= 80000 ) { + $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 != '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 = ?; + }; + } + else { + $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 + , NULL 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 != '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 $functionname = $functions->{'function_name'} . '( '; + 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'}; + my @names; + + if ( defined($argnames) ) { + $argnames =~ s/{(.*)}/$1/; + @names = split( ',', $argnames ); + } + + # Setup full argument types -- including the name prefix + foreach my $type (@types) { + $sth_FunctionArg->execute($type); + + my $hash = $sth_FunctionArg->fetchrow_hashref; + + if ( $count > 0 ) { + $functionname .= ', '; + } + + if ( scalar(@names) > 0 ) { + $functionname .= $names[$count] . ' '; + } + + if ( $hash->{'namespace'} ne $system_schema ) { + $functionname .= $hash->{'namespace'} . '.'; + } + $functionname .= $hash->{'type_name'}; + + $count++; + } + $functionname .= ' )'; + + 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; + +} ## end sub info_collect($$$$$) + +##### +# 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(); + } +} ## end sub write_using_templates($$$$$) + +###### +# 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);)/&/g; + $string =~ s/</</g; + $string =~ s/>/>/g; + $string =~ s/'/'/g; + $string =~ s/"/"/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; +} ## end sub sql_prettyprint($) + +## +# 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] [dbname [username]] + +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/local/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. + --table=<args> Tables to export. Multiple tables may be provided using a + comma-separated list. + + --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); + diff --git a/postgresql_autodoc/postgresql_autodoc.pl b/postgresql_autodoc/postgresql_autodoc.pl new file mode 100755 index 0000000..fa8ac96 --- /dev/null +++ b/postgresql_autodoc/postgresql_autodoc.pl @@ -0,0 +1,1907 @@ +#!/usr/bin/env perl +# -- # -*- Perl -*-w +# $Header: /cvsroot/autodoc/autodoc/postgresql_autodoc.pl,v 1.21 2008/03/12 19:00:56 rbt Exp $ +# Imported 1.22 2002/02/08 17:09:48 into sourceforge + +# Postgres Auto-Doc Version 1.31 + +# License +# ------- +# Copyright (c) 2001-2007, 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 + # @@TEMPLATE-DIR@@ will be replaced by make in the build phase + my $template_path = '@@TEMPLATE-DIR@@'; + + # 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 $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; + }; + + # 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, $statistics, $table_out ); + + # Write out *ALL* templates + write_using_templates( \%db, $database, $statistics, $template_path, + $output_filename_base, $wanted_output ); +} ## end sub main($) + +## +# info_collect +# +# Pull out all of the applicable information about a specific database +sub info_collect { + my ( $dbConnect, $db, $database, $only_schema, $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 . '$'; + } + + # + # 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 + , relhasindex as hasindexes + , relhasrules as hasrules + , reltriggers as hastriggers + , 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 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; + if ( $dbh->{pg_server_version} >= 70400 ) { + $sql_Constraint = q{ + SELECT pg_get_constraintdef(oid) AS constraint_source + , conname AS constraint_name + FROM pg_constraint + WHERE conrelid = ? + AND contype = 'c'; + }; + } + else { + $sql_Constraint = q{ + SELECT 'CHECK ' || pg_catalog.substr(consrc, 2, length(consrc) - 2) 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; + if ( $dbh->{pg_server_version} >= 80000 ) { + $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 != '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 = ?; + }; + } + else { + $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 + , NULL 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 != '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 $functionname = $functions->{'function_name'} . '( '; + 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'}; + my @names; + + if ( defined($argnames) ) { + $argnames =~ s/{(.*)}/$1/; + @names = split( ',', $argnames ); + } + + # Setup full argument types -- including the name prefix + foreach my $type (@types) { + $sth_FunctionArg->execute($type); + + my $hash = $sth_FunctionArg->fetchrow_hashref; + + if ( $count > 0 ) { + $functionname .= ', '; + } + + if ( scalar(@names) > 0 ) { + $functionname .= $names[$count] . ' '; + } + + if ( $hash->{'namespace'} ne $system_schema ) { + $functionname .= $hash->{'namespace'} . '.'; + } + $functionname .= $hash->{'type_name'}; + + $count++; + } + $functionname .= ' )'; + + 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; + +} ## end sub info_collect($$$$$) + +##### +# 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(); + } +} ## end sub write_using_templates($$$$$) + +###### +# 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);)/&/g; + $string =~ s/</</g; + $string =~ s/>/>/g; + $string =~ s/'/'/g; + $string =~ s/"/"/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; +} ## end sub sql_prettyprint($) + +## +# 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] [dbname [username]] + +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: @@TEMPLATE-DIR@@) + -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. + --table=<args> Tables to export. Multiple tables may be provided using a + comma-separated list. + + --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); + diff --git a/postgresql_autodoc/xml.tmpl b/postgresql_autodoc/xml.tmpl new file mode 100644 index 0000000..d589930 --- /dev/null +++ b/postgresql_autodoc/xml.tmpl @@ -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> + diff --git a/postgresql_autodoc/zigzag.dia.tmpl b/postgresql_autodoc/zigzag.dia.tmpl new file mode 100644 index 0000000..2b9f952 --- /dev/null +++ b/postgresql_autodoc/zigzag.dia.tmpl @@ -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> |
