#!/bin/sh
# Utilities needed
# 1. sh
# 2. mv
# 3. sed 
LC_MESSAGES=C
export LC_MESSAGES
if [ "$1" = "--help" -o "$1" = "-h" ]; then
	echo "$0 Upgrade Postgres Pro database cluster to a new minor version"
	echo ""
	echo " $0 [-D directory | --pgdata directory ] " 
	echo ""
	echo "Upgrades the specified database cluster to the current version. This utility "
	echo "performs upgrades between minor versions only."
	echo "The database cluster can be specified either in the PGDATA environment variable,"
	echo "or via -D/--pgdata option in the command line."
	echo ""
	echo " $0 [--pgdata directory ] --check"
	echo ""
	echo "Returns zero code if the specified database cluster does not need an upgrade,"
	echo "and non-zero otherwise."
	echo ""
	echo "This script should be run as user, who owns the database files,"
	echo "typically 'postgres'."
	exit 0
fi
check=
while [ -n  "$*" ]; do
	if [ "$1" = "--check" ]; then
   		check=1
		shift
	elif [ "$1" == "--pgdata" -o "$1" = "-D" ]; then
		PGDATA="$2"
		export PGDATA
		shift;
		shift
	else
		echo "Unrecognized command line option $1" 1>&2
		exit 2;
	fi
done

if [ -z "$PGDATA" ]; then
	echo "PGDATA environment variable is not set. Stop." 1>&2
	exit 2
fi
if [ -e "$PGDATA/recovery.conf" ]; then
	echo "recovery.conf exists in PGDATA. No upgrade script could be run." 1>&2
	exit 0
fi
PGBIN="`echo $0|sed 's![^/\\]*$!!'`"
#echo "$PGBIN"

case "$PGBIN" in
*/bin/|*\\bin\\)
	PGSHARE="`echo $PGBIN|sed 's!bin.$!share!'`"
	;;
*) PGBIN=""
	PGSHARE=""
;;
esac

# Check the catalog version
CATALOG_VERSION_NO=201608131
MAJORVER=9.6
# catalog version upgrade supported from. Space-separated list
UPGRADABLE_CATVER="201608131"
if [ ! -f "${PGDATA}/global/pg_control" -a -f "${PGDATA}/postgresql.conf" ]; then
	# looks like we have Debian with separate directory for configs
	SAVE_PGDATA="$PGDATA"
	PGDATA=`sed -n "/data_directory/{s/^data_directory = '//
	s/'.*$//
	p}" ${PGDATA}/postgresql.conf`
	if [ -z "$PGDATA" -o ! -f "${PGDATA}/global/pg_control" ]; then
		echo "Cannot find valid database in $PGDATA" 1>&2;
		exit 1
	fi
fi
CATVER=`"${PGBIN}pg_controldata"|sed -n '/Catalog version number:/s/^.*: *//p'`
if [ "$CATVER" != $CATALOG_VERSION_NO ]; then
	for v in $UPGRADABLE_CATVER; do
		if [ "$CATVER" = "$v" ]; then
			upgrade_possible=1
			break
		fi
	done
	if [ -z "$upgrade_possible" ];  then
		echo "Upgrade of $PGDATA  from catalog version '$CATVER' is not supported" >&2
		exit 2
	fi

    if [ -n "$check" ]; then
        echo "Database needs upgrade"
        exit 1
    fi
	if [ -f "$PGDATA/postmaster.pid" ]; then
		echo "postmaster.pid exists. Is another backend running on $PGDATA" 1>&2; 
		exit 1;
	fi
	# Fix pg_control file
	"${PGBIN}pg_controldata" -c
	# Fix tablespace directories
	(cd "$PGDATA/pg_tblspc"
	 for i in *; do
	 	[ "$i" = "*" ] && break # Glob pattern not expanded
		(cd $i; mv PG_${MAJORVER}_$CATVER PG_${MAJORVER}_$CATALOG_VERSION_NO)
	 done
	)
fi

if [ -n "$SAVE_PGDATA" ]; then
	PGDATA="$SAVE_PGDATA"
fi

for dir in "$PGSHARE" /usr/pgsql-9.6/share /usr/share/postgresql/9.6 /usr/pgsql/9.6/share /usr/share/pgsql /usr/share/postgrespro96  ; do
	if [ -d "$dir/pgpro-upgrade" ]; then
		DIR="$dir/pgpro-upgrade"
		break
	fi
done
if [ -z "$DIR" ]; then
	echo "Cannot find feature scripts" 1>&2
	exit 1
fi
BASELIST=`echo "select datname from pg_database;"|
	"${PGBIN}postgres" --single template0 |
	sed -n 's/^.*1: datname = "\([^"]*\)".*$/\1/p'`

if [ -z "$BASELIST" ]; then
	echo "Databases for upgrade not found" 1>&2
	exit 1
fi

[ -z "$check" ]&& echo "Upgrading databases $BASELIST"

#Search for upgrade scripts
need_upgrade=0
for i in "$DIR"/*.test; do
	found=`< "$i"  "${PGBIN}postgres" --single template0 | 
		sed -n 's/^[	 ]*1: [^ ]* = "\([ft]\)"[ 	].*$/\1/p'` 
	if [ "$found" = "f" ]; then	
		if [ -z "$check" ]; then
			create="`echo "$i" |sed 's/\.test$/.sql/'`"
			for base in $BASELIST; do
				echo "Executing $create in $base"
				< "$create"  "${PGBIN}postgres" --single "$base" >/dev/null

			done
		else 
			need_upgrade=1
		fi
	fi
done
if [ -n "$check" ]; then
	if [ $need_upgrade -eq 0 ]; then
		echo "All Postgres Pro specific updates are applied" 1>&2
	else
		echo "Database needs upgrade"
	fi
	exit $need_upgrade
fi
