#!/bin/sh

#
# Netmagis database upgrade
#
# Supported upgrade path from 2.0 to all current Netmagis versions.
#
# Syntax :
#	netmagis-dbupgrade [-f netmagis-conf] [target-version]
#

usage ()
{
    (
	echo "usage: $0 [-f netmagis.conf] [target-version]"
	echo "Without argument: display actual versions"
	echo "With target argument: upgrade database to this version"
    ) >&2
    exit 1
}

# Directory where upgrade scripts are located
UPGRADEDIR=/usr/local/lib/netmagis/upgrade

##############################################################################
# Configuration file read
##############################################################################

init_env ()
{

    # Main netmagis database parameters (dnsdb*)
    varlist="dnsdbhost dnsdbport dnsdbname dnsdbuser dnsdbpassword"
    eval $(/usr/local/bin/netmagis-config -f $_conffile -c $varlist)

    if [ $? != 0 ]
    then
	usage
	exit 1
    fi

    PGHOST="$dnsdbhost"
    PGPORT="$dnsdbport"
    PGDATABASE="$dnsdbname"
    PGUSER="$dnsdbuser"
    PGPASSWORD="$dnsdbpassword"
    export PGHOST PGPORT PGDATABASE PGUSER PGPASSWORD

    # Mac database parameters (macdb*)
    varlist="macdbhost macdbport macdbname macdbuser macdbpassword"
    eval $(/usr/local/bin/netmagis-config -f $_conffile -c $varlist)

    if [ $? != 0 ]
    then
	usage
	exit 1
    fi

    # Other configuration parameters
    varlist="_version"
    eval $(/usr/local/bin/netmagis-config -f $_conffile -c $varlist)

    if [ $? != 0 ]
    then
	usage
	exit 1
    fi
}

##############################################################################
# Test if column exists
##############################################################################

# $1 : schema
# $2 : table
# $3 : column
column_exists ()
{
    count=$(psql --quiet --no-psqlrc --tuples-only --no-align \
		    -c "SELECT 1-COUNT(*) FROM information_schema.columns
		    		WHERE table_schema = '$1'
				    AND table_name = '$2'
				    AND column_name = '$3'
		    	")
    return $count
}

##############################################################################
# Database version heuristic
##############################################################################

detect_schema_version ()
{
    v=-1			# unrecognized
    if column_exists global config key
    then
	v=$(psql --quiet --no-psqlrc --tuples-only --no-align \
			-c "SELECT value FROM global.config
					WHERE key = 'schemaversion'")
    elif column_exists topo confcmd idccmd
    then v=21
    elif column_exists topo sensor id
    then v=20
    else v=0			# pre-2.0
    fi
    echo $v
}

##############################################################################
# Check target path
##############################################################################

# $1 = current version
# $2 = target version
check_target_path ()
{
    begin=$1
    end=$2

    # get all upgrade directories
    list=$(cd $UPGRADEDIR ; ls -d *-* | sort -n)

    # skip directories not in path
    lastto=""
    path=""
    for d in $list
    do
	from=$(echo $d | sed 's/-.*//')
	to=$(echo $d | sed 's/.*-//')
	if [ $from = $begin -a $to -le $end ]
	then
	    path="$path $d"
	    begin=$to
	    lastto=$to
	fi
    done
    # is the target version equal to the last item in the path?
    if [ "$end" != "$lastto" ]
    then
	path=""
    fi
    echo $path
}


##############################################################################
# SQL file execution
##############################################################################

# $1 = file (relative to /usr/local/lib/netmagis)
sql_file_execute ()
{
    PGCLIENTENCODING=utf8
    export PGCLIENTENCODING

    psql --no-psqlrc --quiet --file /usr/local/lib/netmagis/$1 2>&1 \
	| grep -v 'NOTICE: .* will create implicit'
}

##############################################################################
# Language creation
##############################################################################

# $1 = language
# exits if creation failed
create_language ()
{
    if psql --quiet --no-psqlrc -c "CREATE EXTENSION IF NOT EXISTS $1"
    then :
    else
	echo "Unable to create language "$1" in database '$PGDATABASE'" >&2
	exit 1
    fi
}

##############################################################################
# Create netmagis database
##############################################################################

create_netmagis ()
{
    echo "Creating main Netmagis database as '$dnsdbname'"

    PGHOST="$dnsdbhost"
    PGPORT="$dnsdbport"
    PGDATABASE="$dnsdbname"
    PGUSER="$dnsdbuser"
    PGPASSWORD="$dnsdbpassword"
    export PGHOST PGPORT PGDATABASE PGUSER PGPASSWORD

    ###############################
    # Create main netmagis database
    ###############################

    if db_create_if_not_exists
    then :
    else
	echo "Erreur while creating database '$PGDATABASE'" 2>&1
	exit 1
    fi

    # exit if schema already exist
    if db_test_schemas "global" "dns" "topo" "pgauth"
    then
	exit 1
    fi

    ###############################
    # Initialize main netmagis database schemas and contents
    ###############################

    create_language plpgsql
    create_language pltcl

    create_netmagis_schemas

    netmagis_insert_config

    ###############################
    # Create netmagis application users
    ###############################

    for u in $rootusers
    do
	netmagis_create_user $u
    done

    netmagis_create_user $defuser

    if [ "$pwgen" = "" -o "$crypt" = "" ]
    then
	echo "Netmagis configuration parameter 'pwgen' and/or 'crypt' uninitialized" >&2
	echo "Users $rootusers have been created" >&2
    else
	echo "You can change passwords within netmagis application" >&2
    fi
}


##############################################################################
# Main program
##############################################################################

#
# Get default configuration file location
#
eval $(/usr/local/bin/netmagis-config -c _conffile)


#
# Syntax checking
#       
 
args=$(getopt hf: $*)

if [ $? != 0 ]
then usage
fi

set -- $args

while true
do
    case "$1" in
	-h) usage
	    exit 0
	    ;;
	-f) _conffile=$2
	    shift 2
	    ;;
	--) shift
	    break
	    ;;
    esac
done

case $# in
    0)	target="" ;;
    1)	target="$1" ;;
    *)	usage ;;
esac

#
# Initialize environnement
#

init_env

#
# Detect versions
#

schemaversion=$(detect_schema_version)
codeversion=$(echo $_version | sed 's/^\([0-9][0-9]*\)\.\([0-9][0-9]*\).*/\1\2/')

if [ $schemaversion -gt $codeversion ]
then
    echo "Database schema ($schemaversion) is not yet recognized by Netmagis ($codeversion)" >&2
    exit 1
fi

#
# Just stop here if no target is specified
#

if [ -z "$target" ]
then
    echo "Detected schema version: $schemaversion"
    echo "Latest schema supported: $codeversion"
    exit 0
fi

#
# Check upgrade path
#

upgrade_path=$(check_target_path $schemaversion $target)
if [ -z "$upgrade_path" ]
then
    echo "Cannot find an upgrade path from $schemaversion to $target." >&2
    exit 0
fi

#
# Perform upgrade
#

echo "Preparing upgrade from $schemaversion to $target."

TMP=/tmp/netmagis-dbupdate.$$

for d in $upgrade_path
do
    u=$UPGRADEDIR/$d/upgrade.sql
    if [ -f $u ]
    then
	echo "\\echo Upgrading: $d"
	echo "\\i $u"
    fi
done > $TMP

PGOPTIONS='--client-min-messages=warning'
export PGOPTIONS

if psql --quiet --no-psqlrc --single-transaction -f $TMP
then
    echo "Upgrade successful" >&2
    r=0
else
    echo "Upgrade error. Aborted" >&2
    r=1
fi

rm -f $TMP

exit $r
