/*
  -----------------------------------------------------------------------------

  module: vcn45.cpp

  -----------------------------------------------------------------------------

  responsible:  BerndV

  special area: DBMServer high level commands

  description:  DBMServer high level commands - Implementation

  -----------------------------------------------------------------------------



    ========== licence begin  GPL
    Copyright (c) 2002-2005 SAP AG

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
    ========== licence end




*/

/*
  -----------------------------------------------------------------------------
  includes
  -----------------------------------------------------------------------------
 */
// this module
#include "hcn45.h"

// cn modules
#include "hcn20.h"
#include "hcn40.h"
#include "hcn80.h"
#include "hcn90.h"

// other sap db modules
//#include "idl/expat/expat.h"

/*
  -----------------------------------------------------------------------------
  public function cn45MigrateCatalog
  -----------------------------------------------------------------------------
*/
tcn00_Error cn45MigrateCatalog
      ( VControlDataT * vcontrol,
        CommandT      * command,
        char          * replyData,
        int           * replyLen,
        int             replyLenMax)
{
  FUNCTION_DBG_MCN00_1("cn45MigrateCatalog");

  tcn00_Error    nFuncReturn = OK_CN00;
  tcn002_XpValueString szOldPacketSize;
  bool           bParamsSet = false;

  // 1. check the database state; it has to be offline
  if (nFuncReturn == OK_CN00) {
    if (cn90DBState(vcontrol->dbname) != STATE_OFFLINE_CN00) {
      teo200_EventList aEvent(FUNCTION_NAME_MCN00_1, ERR_DBRUN_CN00_1);
      nFuncReturn = cn90AnswerEvent(replyData, replyLen, aEvent);
    } // end if
  } // end if

  // 2. check the param dirty flag; it has to be clear
  if (nFuncReturn == OK_CN00) {
    tsp00_Int4        nValue;
    nFuncReturn = cn20XParamGetValue(vcontrol->dbname, PAN_XPARAM_CHANGED, nValue);
    if (nFuncReturn == OK_CN00) {
      if (nValue == 1) {
        teo200_EventList aEvent(FUNCTION_NAME_MCN00_1, ERR_XPDIRTY_CN00_1);
        nFuncReturn = cn90AnswerEvent(replyData, replyLen, aEvent);
      } // end if
    } else {
      nFuncReturn = cn90AnswerIError(replyData, replyLen, nFuncReturn);
    } // end if
  } // end if

  // 3. check the _UNICODE parameter; it has to be "NO"
  if (nFuncReturn == OK_CN00) {
    tcn002_XpValueString     szValue;
    nFuncReturn = cn20XParamGetValue(vcontrol->dbname, PAN_UNICODE_CATALOG, szValue);
    if (nFuncReturn == OK_CN00) {
      if (strcmp(szValue, "NO") != 0) {
        teo200_EventList aEvent1(FUNCTION_NAME_MCN00_1, 1,  TERR_CN00_1, "DBM", "Parameter %s is already %s.", PAN_UNICODE_CATALOG, szValue.asCharp());
        teo200_EventList aEvent(aEvent1, FUNCTION_NAME_MCN00_1, ERR_PARAM_CN00_1);
        nFuncReturn = cn90AnswerEvent(replyData, replyLen, aEvent);
      } // end if
    } else {
      nFuncReturn = cn90AnswerIError(replyData, replyLen, nFuncReturn);
    } // end if
  } // end if

  // 4. Read _PACKET_SIZE
  if (nFuncReturn == OK_CN00) {
    nFuncReturn = cn20XParamGetValue(vcontrol->dbname, PAN_PACKET_SIZE, szOldPacketSize);
    if (nFuncReturn != OK_CN00) {
      nFuncReturn = cn90AnswerIError(replyData, replyLen, nFuncReturn);
    } // end if
  } // end if
  
  // 5. change and check parameters
  if (nFuncReturn == OK_CN00) {
    const char * szNames[]  = {PAN_PACKET_SIZE, PAN_UNICODE_CATALOG};
    const char * szValues[] = {"131072"       , "YES"};

    command->args = "";
    nFuncReturn = cn20CheckedParamPut ( vcontrol,
                                        command,
                                        replyData,
                                        replyLen,
                                        replyLenMax,
                                        2,
                                        szNames,
                                        szValues);
    bParamsSet = (nFuncReturn == OK_CN00);
  } // end if

  // 6. database to admin
  if (nFuncReturn == OK_CN00) {
    command->args = "";
    nFuncReturn = cn40DBCold( vcontrol,
                              command,
                              replyData,
                              replyLen,
                              replyLenMax);
  } // end if

  // 7. disable log
  if (nFuncReturn == OK_CN00) {
    nFuncReturn = cn80ExecuteUtil(vcontrol->dbname, DB_DISABLE_LOG_CN80, replyData, replyLen);
  } // end if

  // 8. migrate catalaog
  if (nFuncReturn == OK_CN00) {
    nFuncReturn = cn80ExecuteUtil(vcontrol->dbname, DB_MIGRATE_CATALOG_CN80, replyData, replyLen);
  } // end if

  // 9. on error reset params
  if ((nFuncReturn != OK_CN00) && bParamsSet) {
    char         tmpReplyData[1001];
    int          tmpReplyLen;
    const char * szNames[]  = {PAN_PACKET_SIZE,           PAN_UNICODE_CATALOG};
    const char * szValues[] = {szOldPacketSize.asCharp(), "NO"};

    command->args = "";
    cn20CheckedParamPut ( vcontrol,
                          command,
                          tmpReplyData,
                          &tmpReplyLen,
                          1000,
                          2,
                          szNames,
                          szValues);
  } // end if

  // 10. check database state
  if (nFuncReturn == OK_CN00) {
    if (cn90DBState(vcontrol->dbname) != STATE_ONLINE_CN00) {
      teo200_EventList aEvent(FUNCTION_NAME_MCN00_1, ERR_DBNORUN_CN00_1);
      nFuncReturn = cn90AnswerEvent(replyData, replyLen, aEvent);
    } // end if
  } // end if

  // 11. load system tables
  if (nFuncReturn == OK_CN00) {
    command->args = "-m";
    nFuncReturn = cn40LoadSysTab( vcontrol,
                                  command,
                                  replyData,
                                  replyLen,
                                  replyLenMax);
  } // end if

  // 12. database to offline
  if (nFuncReturn == OK_CN00) {
    command->args = "";
    nFuncReturn = cn40DBOffline( vcontrol,
                                 command,
                                 replyData,
                                 replyLen,
                                 replyLenMax);
  } // end if

  // 13. reset packetsize
  if (nFuncReturn == OK_CN00) {
    const char * szNames[]  = {PAN_PACKET_SIZE};
    const char * szValues[] = {szOldPacketSize.asCharp()};

    command->args = "";
    nFuncReturn = cn20CheckedParamPut ( vcontrol,
                                        command,
                                        replyData,
                                        replyLen,
                                        replyLenMax,
                                        1,
                                        szNames,
                                        szValues);
  } // end if

  // 14. database to admin
  if (nFuncReturn == OK_CN00) {
    command->args = "";
    nFuncReturn = cn40DBCold( vcontrol,
                              command,
                              replyData,
                              replyLen,
                              replyLenMax);
  } // end if

  // 15. enable log
  if (nFuncReturn == OK_CN00) {
    nFuncReturn = cn80ExecuteUtil(vcontrol->dbname, DB_ENABLE_LOG_CN80, replyData, replyLen);
  } // end if

  // 16. database to warm
  if (nFuncReturn == OK_CN00) {
    command->args = "";
    nFuncReturn = cn40DBWarm( vcontrol,
                              command,
                              replyData,
                              replyLen,
                              replyLenMax);
  } // end if

  if (nFuncReturn == OK_CN00) {
    cn90AnswerOK(replyData, replyLen, NULL);
  } // end if

  return nFuncReturn;
} // end cn45MigrateCatalog

/*
  -----------------------------------------------------------------------------
  public function cn45Reinstall
  -----------------------------------------------------------------------------
*/
tcn00_Error cn45Reinstall
      ( VControlDataT * vcontrol,
        CommandT      * command,
        char          * replyData,
        int           * replyLen,
        int             replyLenMax)
{
  FUNCTION_DBG_MCN00_1("cn45Reinstall");

  tcn00_Error    nFuncReturn = OK_CN00;

  // 1. check the database state; it has to be offline
  if (nFuncReturn == OK_CN00) {
    if (cn90DBState(vcontrol->dbname) != STATE_OFFLINE_CN00) {
      teo200_EventList aEvent(FUNCTION_NAME_MCN00_1, ERR_DBRUN_CN00_1);
      nFuncReturn = cn90AnswerEvent(replyData, replyLen, aEvent);
    } // end if
  } // end if


  // 2. Load and check Users
  cn50DBMUser  usrDBA(vcontrol->dbname, cn50DBMUser::getSYSDBA(vcontrol->dbname));
  cn50DBMUser  usrDOMAIN(vcontrol->dbname, cn50DBMUser::getDOMAIN(vcontrol->dbname));
  if (nFuncReturn == OK_CN00) {
    if (usrDBA.lastEvent()) {
      teo200_EventList aEvent(FUNCTION_NAME_MCN00_1, ERR_DBAUNKNOWN_CN00_1);
      nFuncReturn = cn90AnswerEvent(replyData, replyLen, aEvent);
    } else if (usrDOMAIN.lastEvent()) {
      teo200_EventList aEvent(FUNCTION_NAME_MCN00_1, ERR_DOMPUNKNOWN_CN00_1);
      nFuncReturn = cn90AnswerEvent(replyData, replyLen, aEvent);
    } // end if
  } // end if

  // 3. database to admin
  if (nFuncReturn == OK_CN00) {
    nFuncReturn = cn40DBCold( vcontrol,
                              command,
                              replyData,
                              replyLen,
                              replyLenMax);
  } // end if

  // 3. create instance
  if (nFuncReturn == OK_CN00) {
    char szCommand[1000];
    sprintf(szCommand, DB_CREATE_CN80, usrDBA.getUserName().asCharp(), usrDBA.getClearMasterPwd().asCharp());
    nFuncReturn = cn80ExecuteUtil(vcontrol->dbname, szCommand, replyData, replyLen);
  } // end if

  // 4. load system tables
  if (nFuncReturn == OK_CN00) {
    char szCommand[1000];
    sprintf(szCommand, "-ud %s", usrDOMAIN.getClearMasterPwd().asCharp());
    const char * pArgs = command->args;
    command->args = &szCommand[0];
    usrDOMAIN.deleteUsr();
    nFuncReturn = cn40LoadSysTab( vcontrol,
                                  command,
                                  replyData,
                                  replyLen,
                                  replyLenMax);
    command->args = pArgs;
  } // end if

  if (nFuncReturn == OK_CN00) {
    cn90AnswerOK(replyData, replyLen, NULL);
  } // end if

  return nFuncReturn;
} // end cn45Reinstall

/*
  -----------------------------------------------------------------------------
  public function cn45DBInstall
  -----------------------------------------------------------------------------
*/
/*
tcn00_Error cn45DBInstall
      ( VControlDataT * vcontrol,
        CommandT      * command,
        char          * replyData,
        int           * replyLen,
        int             replyLenMax)
{
  FUNCTION_DBG_MCN00_1("cn45Reinstall");

  tcn00_Error    nFuncReturn = OK_CN00;

  // expat test
  XML_Parser oParser;

  oParser = XML_ParserCreate(NULL);
  
  if (!oParser) {
    nFuncReturn =  cn90AnswerIError(replyData, replyLen, ERR_MEM_CN00);
  } // end if

  if (nFuncReturn == OK_CN00) {
    cn90AnswerOK(replyData, replyLen, NULL);
  } // end if

  return nFuncReturn;
} // end cn45DBInstall
*/