#!/bin/sh

 # Copyright (c) 2008 Pierre-Emmanuel Andre <pea@raveland.org>
 # 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. The name of the author may not be used to endorse or promote products
 #    derived from this software without specific prior written permission.
 #
 # THIS SOFTWARE IS PROVIDED ``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 AUTHOR 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.
 #

usage="usage: dbrelationsize [-t] [-i] [-s] [-H host] -d dbname\
\n-t show sizes of tables (default)\
\n-i show sizes of indexes \
\n-s show sizes of sequences \
\n-v show sizes of views \
\n-H specifies the hostname of the machine on wich the server is running\
\n-d specifies the database name name (default template1)"

HOST=""
DATABASE="template1"
TABLE=""
INDEX=""
SEQ=""
VIEW=""

while getopts "H:d:htisv" options; do
  case $options in
    t ) TABLE="'r'," ;;
    i ) INDEX="'i'," ;;
    s ) SEQ="'S'," ;;
    v ) VIEW="'v'," ;;
    H ) HOST="-h $OPTARG";;
    d ) DATABASE=$OPTARG;;
    h ) echo -e $usage
         exit 1;;
    \? ) echo -e $usage
         exit 1;;
    * ) echo -e $usage
          exit 1;;
  esac
done

#default choice
[[ -z $TABLE && -z $INDEX && -z $SEQ && -z $VIEW ]] && TABLE="'r',"

Q="SELECT n.nspname as \"Schema\", c.relname as \"Name\",\
CASE c.relkind WHEN 'r' THEN 'table' WHEN 'v' THEN 'view' \
WHEN 'i' THEN 'index' WHEN 'S' THEN 'sequence' WHEN 's' THEN \
'special' END as \"Type\", \
pg_size_pretty(pg_relation_size(c.relname)) as size \
FROM pg_catalog.pg_class c \
JOIN pg_catalog.pg_roles r ON r.oid = c.relowner \
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace \
WHERE c.relkind IN ($TABLE $INDEX $SEQ $VIEW '') \
AND n.nspname <> 'pg_catalog' \
AND n.nspname !~ '^pg_toast' \
AND pg_catalog.pg_table_is_visible(c.oid) \
ORDER BY 1,2; "

psql $HOST -d $DATABASE -c "$Q"
RETURN=$?

if [ $RETURN -ne 0 ]
then
    echo "\nTry $(basename $0) -h to see help"
fi

exit $RETURN

=head1 NAME

dbrelationsize - Returns relations size

=head1 SYNOPSIS

dbrelationsize [-t] [-i] [-s] [-v] [-H hostname] -d name

=head1 OPTIONS

=over

=item -t

show sizes of tables

=item -i

show sizes of indexes

=item -s

show sizes of sequences

=item -v

show sizes of views

=item -H hostname

connect to database server B<hostname>

=item -d name

print size of database B<name>

=back

=head1 ENVIRONMENT

B<PGDATABASE>, B<PGHOST>, B<PGPORT>, B<PGUSER> as described in psql(1).

=head1 AUTHOR

the "dbrelationsize" program: Pierre-Emmanuel Andre < pea at raveland.org>

=cut
