#!/usr/bin/sh
#
# BAREOS® - Backup Archiving REcovery Open Sourced
#
# Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
# Copyright (C) 2013-2024 Bareos GmbH & Co. KG
#
# This program is Free Software; you can redistribute it and/or
# modify it under the terms of version three of the GNU Affero General Public
# License as published by the Free Software Foundation and included
# in the file LICENSE.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
#
# This script will update a BAREOS database to the latest version.
#
set -e
set -u

# avoid misleading PostgreSQL warning 'could not change directory to ...'
cd /

#
# Source the Bareos config functions.
#
. "/usr/lib/bareos/scripts"/bareos-config-lib.sh

db_name="${db_name:-$(get_database_name bareos)}"
db_user="${db_user:-$(get_database_user bareos)}"
db_version=$(get_database_version)
bareos_sql_ddl="$(get_database_ddl_dir)"
temp_sql_schema="/tmp/tables.sql.$$"

SHOW_WARNING="yes"

if [ $# -gt 0 ]; then
  handle_database_scripts_command_line_parameter $*
fi
# Below this line no additional parameters is allowed in command ($*)
info "Updating ${db_name} tables"

while true
do
    DBVERSION=$(PGOPTIONS='--client-min-messages=warning' psql --no-psqlrc -d "${db_name}" -t --pset format=unaligned -c "SELECT MAX(VersionId) FROM Version;" | tr -d '\r')
    if [ -z "${DBVERSION}" ]; then
        error "Unable to determine version of Bareos database"
        exit 1
    fi

    if [ "${DBVERSION}" -eq "${db_version}" ]; then
      info "Finished upgrading database to version ${db_version}"
      exit 0
    fi

    #
    # See if its a known conversion.
    #
    found=0
    known_conversions=$(ls "${bareos_sql_ddl}"/updates/postgresql* 2>/dev/null| \
                      sed -e 's#.*/##' | \
                      cut -d'.' -f2 | \
	              tr -d '\r')
   for conversion in ${known_conversions}; do
      start_version=$(echo "${conversion}" | cut -d_ -f1 | tr -d '\r')
      end_version=$(echo "${conversion}" | cut -d_ -f2 | tr -d '\r')

      if [ "${start_version}" -eq "${DBVERSION}" ]; then
         found=1
         break
      fi
   done

   if [ "${found}" -eq 0 ]; then
      error "Don't know how to upgrade from version ${DBVERSION} to ${db_version}"
      exit 1
   fi

   if [ "${SHOW_WARNING}" = "yes" ] && [ "${DBVERSION}" -lt 2171 ]; then
      warn "WARNING:"
      warn "  Updating the database to schema version 2171 will increase the required disk space."
      warn "  Especially it will require around twice the amount of disk space, during the migration."
      if [ "${FORCE}" != "yes" ]; then
         info "  Please verify you got enough disk space available and confirm by pressing <ENTER>."
         read input
         # warning already shown and confirmed. No need to show it again.
         SHOW_WARNING="no"
      fi
   fi

   sql_definitions="${bareos_sql_ddl}/updates/postgresql.${conversion}.sql"
   if [ ! -f "${sql_definitions}" ]; then
      error "Unable to open database update definitions in file ${sql_definitions}"
      exit 1
   fi

   sed -e "s/@DB_NAME@/${db_name}/" \
       -e "s/@DB_USER@/${db_user}/" \
       "${sql_definitions}" > "${temp_sql_schema}"

   info "Upgrading database schema from version ${start_version} to ${end_version}"
   retval=0
   case $(uname -s) in
    *_NT*)
      PAGER="" PGOPTIONS="--client-min-messages=warning" psql --no-psqlrc -f "$(cygpath -w "${temp_sql_schema}")" -d "${db_name}" || retval=$?
      ;;
    *)
      PAGER="" PGOPTIONS="--client-min-messages=warning" psql --no-psqlrc -f "${temp_sql_schema}" -d "${db_name}" || retval=$?
      ;;
   esac
   if [ ${retval} -ne 0 ]; then
      error "Failed to upgrade database schema from version ${start_version} to ${end_version}"
      exit ${retval}
   fi
   rm -f "${temp_sql_schema}"
   #
   # return value of psql is does says OK when transaction was rolled back.
   # So we verify that the version was set to what we expect.
   #
   DBVERSION_AFTER=$(PGOPTIONS='--client-min-messages=warning' psql --no-psqlrc -d "${db_name}" -t --pset format=unaligned -c "SELECT MAX(VersionId) FROM Version;" | tr -d '\r')
   if [ "${DBVERSION_AFTER}" -ne "${end_version}" ]; then
      error "Failed to upgrade database schema from version ${DBVERSION} to ${end_version}, is still on ${DBVERSION_AFTER}"
      exit 1
   fi

done

exit ${retval}
