/*
  -----------------------------------------------------------------------------
  module: vls31_catalogextract.cpp
  -----------------------------------------------------------------------------

  responsible:  d033893, SteffenS

  special area: Loader

  description:  Implementation of the CATALOGEXTRACT/CATALOGLOAD functionality

  version:      7.5.
  -----------------------------------------------------------------------------


    ========== licence begin  GPL
    Copyright (c) 2000-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



*/

#include "gls00.h"
#include "hls03.h"
#include "hls15.h"
#include "hls30.h"
#include "hls99.h"
#include "hls31_odbc_Result.h"
#include "hls31_catalogextract.h"

/* -----------------------------------------------------------------------------
   ls31ExecCatTransform
/-------------------------------------------------------------------------------*/
SAPDB_Int4
ls31ExecCatTransform(MetaDataDef    *&pMetaDataDef,
                     tls00_DBInfo   *pDBInfo,
                     tsp00_Addr     ErrText)
{
    ROUTINE_DBG_MEO00 ("ls31ExecCatTransform");

    LoaderMessages *pMsgInstance = LoaderMessages::Instance();
    SAPDB_Long rc = errOK_els00;

    TransformationDef       * pTransformationDef  = pMetaDataDef->getTransformationModel();
    tls00_TransformationCmd * pTransformationCmd  = pTransformationDef->getTransformationCmd();

    StudioOAL_String  ErrorText;

    //*
    //*   check if user is sysdba 
    //*
	if (ptAll_els00 == pTransformationCmd->trPartSpec_ls00.psPartType_ls00 &&
		pTransformationCmd->trCatalogFile_ls00.fsFormat_ls00.ffoXml_ls00 == false )
    {
        rc = ls15CheckUserMode(pDBInfo,
                               pDBInfo->dbiSession_ls00.siUserName_ls00.asCharp(),
                               dbuSysdba_els00,
                               ErrText);
        if (dbRowNotFound_els00 == rc)
		{
            pMsgInstance->ls98Msg(layTableExtract_els98, ErrText, errRestrictedStmt_els98);
			return rc;
		}
    }

    StudioOAL_String   transformationpackage;
    StudioTD_String    username;

    tls00_FileInfo     streamInfo;

    // interpret <catalogextract statement>::=
    // catalogextract <part_spec> OUTFILE <external_file_spec>;
    // <part_spec> :: = all | user | table
    streamInfo.fileSpec = pTransformationCmd->trCatalogFile_ls00;

    if ( errOK_els00 == rc  )
    {
        //*
        //*  initialize stream
        //*
        streamInfo.vFile.vfFileType_ls00   = streamInfo.fileSpec.fsDeviceType_ls00;

        if ( dtypeTape_ls00 == streamInfo.fileSpec.fsDeviceType_ls00 && rc == errOK_els00)
        {
            streamInfo.vFile.vfBackupTool_ls00 = pDBInfo->dbiSession_ls00.siBackupTool_ls00;
            streamInfo.vFile.vfNodeName_ls00.Assign(REINTERPRET_CAST(Tools_DynamicUTF8String::ConstPointer,
                                                                     pDBInfo->dbiSession_ls00.si_pDBNode_ls00));
            streamInfo.vFile.vfDBName_ls00.Assign(REINTERPRET_CAST(Tools_DynamicUTF8String::ConstPointer,
                                                                   pDBInfo->dbiSession_ls00.siDBName_ls00.asCharp()));
        }

        //*
        //* extract catalog ddl, xml
        //*
        if ( tsExport_ls00 == pTransformationCmd->trTransSpec_ls00 )
        {
            //*
            //*  configure transformationpackage
            //*
            //transformationpackage = "LOAD TRANSFORMATIONPACKAGE";
            rc = pTransformationDef->LoadTransformationPackage ( pMetaDataDef, ErrText );

            ls30VFInitialize(streamInfo.vFile, pTransformationCmd->trCatalogFile_ls00.fsFileName_ls00, 
                             sp5vf_text, sp5vf_write, streamInfo.fileSpec.fsFormat_ls00.ffoCodeType_ls00);

            rc = ls30VFOpen (streamInfo.vFile,ErrText);

            if ( rc != errOK_els00 )
                return rc;

            pMetaDataDef->setMedium( streamInfo );
            //*
            //*  execute transformationpackage
            //*
            //transformationpackage = "EXECUTE PACKAGE TO TRANSFORM CATALOG";
            pMsgInstance->ls98PrintMessage(layCatalogExtract_els98, msgCommandExecuting_els98, "EXECUTE PACKAGE TO TRANSFORM CATALOG");

            if ( ptTable_els00  < pTransformationCmd->trPartSpec_ls00.psPartType_ls00 )
            {
                TransformationDef * pTransformationDef = pMetaDataDef->getTransformationModel();
                pMsgInstance->ls98PrintMessage(layCatalogExtract_els98, msgNumTabToTransform_els98    ,pTransformationDef->m_nTableCount);
                pMsgInstance->ls98PrintMessage(layCatalogExtract_els98, msgNumViewToTransform_els98   ,pTransformationDef->m_nViewCount);
                pMsgInstance->ls98PrintMessage(layCatalogExtract_els98, msgNumSynonymToTransform_els98,pTransformationDef->m_nSynonymCount);
            }

            username.Assign(REINTERPRET_CAST(Tools_DynamicUTF8String::ConstPointer,
                                             pDBInfo->dbiSession_ls00.siUserName_ls00.asCharp()));

            //*
            //*  update  transformationpackage
            //*
            RelationalDef* pRelationalDef = pMetaDataDef->getRelationalModel();

            if (ptAll_els00 == pTransformationCmd->trPartSpec_ls00.psPartType_ls00 && rc == errOK_els00)
                rc = pRelationalDef->ExtrCatalogCmd(username, ErrText );
            else if ( ptUser_els00 == pTransformationCmd->trPartSpec_ls00.psPartType_ls00 && rc == errOK_els00 )
                rc = pRelationalDef->ExtrSchemaCmd(username  );
            else if (ptTable_els00 == pTransformationCmd->trPartSpec_ls00.psPartType_ls00 && rc == errOK_els00)
                rc = pRelationalDef->ExtrTableCmd( pTransformationCmd->trPartSpec_ls00 );

            SAPDB_Int4 rcFile = ls30VFClose(streamInfo.vFile,ErrText);
            if ( (errOK_els00 == rc) && (errOK_els00 != rcFile) )
                 rc = rcFile;

            //*
            //*  storagedevice, servernode, serverdb, username, codetype, codepage, transformation, part, streamformat
            //*
            if ( (dtypeTape_ls00 == pTransformationCmd->trCatalogFile_ls00.fsDeviceType_ls00 ) &&
                 (ptTable_els00   < pTransformationCmd->trPartSpec_ls00.psPartType_ls00 )   )
            {
                pTransformationCmd->trCatalogFile_ls00.fsBackupId_ls00.bBackupIdName_ls00 = REINTERPRET_CAST(SAPDB_Char *,(CONST_CAST (unsigned char* ,streamInfo.vFile.vfBackupId_ls00.StrPtr())));
                rc = ls31UpdateTransformationPackage( pMetaDataDef, pTransformationCmd, ErrText);
            }
            //*
            //*  unload  transformationpackage
            //*
            if ( NULL == pTransformationCmd->trDataFile_ls00.fsFileName_ls00  )
                 rc = pTransformationDef->UnloadTransformationPackage( pMetaDataDef, ErrText );

        }//if ( tsExport == pTransformationCmd->trTransSpec_ls00  && rc == errOK_els00 )

        //*
        //* load catalog ddl
        //*
        else if ( tsImport_ls00 == pTransformationCmd->trTransSpec_ls00  )
        {
            if ( dtypeTape_ls00 == pTransformationCmd->trCatalogFile_ls00.fsDeviceType_ls00 )
            {
                streamInfo.vFile.vfBackupId_ls00.Assign(REINTERPRET_CAST(Tools_DynamicUTF8String::ConstPointer,
                                                                         streamInfo.fileSpec.fsBackupId_ls00.bBackupIdName_ls00));
            }

            ls30VFInitialize(streamInfo.vFile, pTransformationCmd->trCatalogFile_ls00.fsFileName_ls00,
                             sp5vf_text, sp5vf_read, streamInfo.fileSpec.fsFormat_ls00.ffoCodeType_ls00);
            rc = ls30VFOpen (streamInfo.vFile, ErrText);
            if (errOK_els00 == rc)
            {
                pMetaDataDef->setMedium( streamInfo );

                username.Assign(REINTERPRET_CAST(Tools_DynamicUTF8String::ConstPointer,
                                                 pDBInfo->dbiSession_ls00.siUserName_ls00.asCharp()));

                //*
                //*  execute transformationpackage
                //*
                RelationalDef* pRelationalDef = pMetaDataDef->getRelationalModel();

                pMsgInstance->ls98PrintMessage(layCatalogLoad_els98, msgCommandExecuting_els98, "EXECUTE PACKAGE TO TRANSFORM CATALOG");

                if (ptAll_els00 == pTransformationCmd->trPartSpec_ls00.psPartType_ls00)
                    rc = pRelationalDef->LoadCatalogCmd(username);
                else if ( ptUser_els00 == pTransformationCmd->trPartSpec_ls00.psPartType_ls00)
                    rc = pRelationalDef->LoadSchemaCmd(username);
                else if (ptTable_els00 == pTransformationCmd->trPartSpec_ls00.psPartType_ls00)
                    rc = pRelationalDef->LoadTableCmd( pTransformationCmd->trPartSpec_ls00, ErrText );

                char _pszTmp[256];
                _pszTmp[0] = 0;

                SAPDB_Int4 rcFile = ls30VFClose(streamInfo.vFile, _pszTmp);
                if ( (errOK_els00 == rc) && (errOK_els00 != rcFile) )
                {
                    rc = rcFile;
                    size_t _len = _tcslen(_pszTmp);
                    SAPDB_memcpy(ErrText, _pszTmp, _len);
                    ErrText[_len] = 0;
                }

                if (errOK_els00 == rc)
                {
                    //*
                    //*  configure transformationpackage
                    //*
                    //transformationpackage = "LOAD TRANSFORMATIONPACKAGE";
                    rc = pTransformationDef->LoadTransformationPackage ( pMetaDataDef, ErrText );
                }
                else if (errOK_els00 != rc && ptTable_els00 < pTransformationCmd->trPartSpec_ls00.psPartType_ls00)
                {
                    ErrorHndl *pError = pMetaDataDef->getError();
                    pMsgInstance->ls98MsgToString(layTableExtract_els98, ErrText, STATIC_CAST(ErrorNumbers, rc), pError->getErrorText().StrPtr());
                }

                if ( ptTable_els00  < pTransformationCmd->trPartSpec_ls00.psPartType_ls00  )
                {
                    pMsgInstance->ls98PrintMessage(layCatalogExtract_els98, msgNumTabTransformed_els98     ,pTransformationDef->m_nTableCount);
                    pMsgInstance->ls98PrintMessage(layCatalogExtract_els98, msgNumViewsTransformed_els98   ,pTransformationDef->m_nViewCount);
                    pMsgInstance->ls98PrintMessage(layCatalogExtract_els98, msgNumSynonymsTransformed_els98,pTransformationDef->m_nSynonymCount);
                }
                //*
                //*  unload  transformationpackage
                //*
                if ( NULL == pTransformationCmd->trDataFile_ls00.fsFileName_ls00  )
                {
                    SAPDB_Int4 rcUNLOAD = pTransformationDef->UnloadTransformationPackage(pMetaDataDef, ErrText);
                    if ( (errOK_els00 == rc) && (errOK_els00 != rcUNLOAD) )
                        rc = rcUNLOAD;
                }

            }
        } // if ( pTransformationCmd->trTransSpec_ls00 == tsImport )

    }// ls31LoadTransformationPackage

    return rc;
}// ls31ExecCatTransform

/* -----------------------------------------------------------------------------
   ls31UpdateTransformationPackage
/-------------------------------------------------------------------------------*/
tsp00_Int4
ls31UpdateTransformationPackage(MetaDataDef*             pMetaDataDef,
                                tls00_TransformationCmd* pTransformationCmd,
                                tsp00_Addr               ErrText)
{
    ROUTINE_DBG_MEO00 ("ls31UpdateTransformationPackage");

    SAPDB_Int4  rc = errOK_els00;

    TransformationDef* pTransformationDef = pMetaDataDef->getTransformationModel();
    tls00_DBInfo*      pDBInfo            = pMetaDataDef->getConnection();

    //*
    //*  update transformation table columns:
    //*  taskid, storagedevice, servernode, serverdb, username, codetype, codepage, transformation, part, streamformat
    //*
    StudioTD_String  servernode;
    StudioTD_String  serverdb;
    StudioTD_String  username;
    StudioOAL_String catalogstreamname;
    StudioOAL_String catalogstreamebid ;

    StudioOAL_String parameter[13];

    SAPDB_Char   destBeg[1000] ;
    SAPDB_UInt4  destAt  = 1000;

    // packageid
    parameter[0]  = "0";
    // servernode
    parameter[1]  = "'";
    memset(destBeg,0,sizeof(destBeg));
    pMetaDataDef->getConnection()->dbiOdbcConnection.GetServerNode( REINTERPRET_CAST(unsigned char*, destBeg ), destAt);
    servernode.ConvertFromASCII_Latin1( destBeg, destBeg+strlen(destBeg));
    parameter[1] += servernode;
    parameter[1] += "'";
    // serverdb
    parameter[2]  = "'";
    memset(destBeg,0,sizeof(destBeg));
    pMetaDataDef->getConnection()->dbiOdbcConnection.GetServerDb ( REINTERPRET_CAST(unsigned char*,destBeg ),destAt);
    serverdb.ConvertFromASCII_Latin1( destBeg, destBeg+strlen(destBeg));
    parameter[2] += serverdb;
    parameter[2] += "'";

    // codetype
    parameter[3] = pszCodeTypeValue_ls00[pDBInfo->dbiSession_ls00.siCodeType_ls00];

    // username
    parameter[4]  = "'";
    memset(destBeg,0,sizeof(destBeg));
    pMetaDataDef->getConnection()->dbiOdbcConnection.GetUser( REINTERPRET_CAST(unsigned char*,destBeg ),destAt);
    username.ConvertFromASCII_Latin1( destBeg, destBeg+strlen(destBeg));
    parameter[4] += username;
    parameter[4] += "'";

    // codepage
    if (ctAscii_els00 == pDBInfo->dbiSession_ls00.siCodeType_ls00)
    {
        parameter[5]  = "'";
        parameter[5] += pDBInfo->dbiSession_ls00.siCodePage_ls00.name.asCharp();
        parameter[5] += "'";
    }
    else
    {
        parameter[5]  = "NULL";
    }

    // storagedevice
    parameter[6]  = pszBackupToolValue_ls00[pDBInfo->dbiSession_ls00.siBackupTool_ls00];
    // transformation
    parameter[7]  = "'EXTRACT'";

    // part
    if (ptAll_els00   == pTransformationCmd->trPartSpec_ls00.psPartType_ls00)
        parameter[8]  = "'ALL'";
    if (ptUser_els00  == pTransformationCmd->trPartSpec_ls00.psPartType_ls00)
        parameter[8]  = "'USER'";
    if (ptTable_els00 == pTransformationCmd->trPartSpec_ls00.psPartType_ls00)
        parameter[8]  = "'TABLE'";

    // catalogstreamname
    if ( NULL != pTransformationCmd->trCatalogFile_ls00.fsFileName_ls00 )
    {
        _TCHAR* pszDest = strrchr(pTransformationCmd->trCatalogFile_ls00.fsFileName_ls00, SLASH_LS00);
        if (NULL == pszDest)
        pszDest = strrchr(pTransformationCmd->trCatalogFile_ls00.fsFileName_ls00, BACKSLASH_LS00);
        if (NULL == pszDest)
            pszDest = pTransformationCmd->trCatalogFile_ls00.fsFileName_ls00;
        pszDest = (pszDest == pTransformationCmd->trCatalogFile_ls00.fsFileName_ls00) ? pszDest : pszDest + 1;

        catalogstreamname.Assign(REINTERPRET_CAST(Tools_DynamicUTF8String::ConstPointer, pszDest));
        parameter[9]  = "'";
        parameter[9] += catalogstreamname;
        parameter[9] += "'";
    }
    // catalogstreamtype

    parameter[10] = pszDeviceTypeValue_ls00[pTransformationCmd->trCatalogFile_ls00.fsDeviceType_ls00];

    if (tsImport_ls00  == pTransformationCmd->trTransSpec_ls00 &&
        dtypeTape_ls00 == pTransformationCmd->trCatalogFile_ls00.fsDeviceType_ls00)
    {
        if ( NULL == pTransformationCmd->trCatalogFile_ls00.fsBackupId_ls00.bBackupIdName_ls00 )
            parameter[11] = catalogstreamebid.AssignRaw(REINTERPRET_CAST(unsigned char*, pDBInfo->dbiSession_ls00.siNullSpec_ls00.asCharp()),
                                                        _tcslen(pDBInfo->dbiSession_ls00.siNullSpec_ls00.asCharp()));
        else
            parameter[11] = catalogstreamebid.AssignRaw(REINTERPRET_CAST(unsigned char*, pTransformationCmd->trCatalogFile_ls00.fsBackupId_ls00.bBackupIdName_ls00),
                                                        _tcslen(pTransformationCmd->trCatalogFile_ls00.fsBackupId_ls00.bBackupIdName_ls00));
    }

    // catalogstreamformat
    if  ( true == pTransformationCmd->trCatalogFile_ls00.fsFormat_ls00.ffoXml_ls00 )
        parameter[12]  =  "'XML'";
    else
        parameter[12]   = "'DDL'";

    if ( !pTransformationDef->updateCatTask(parameter))
    {
        StudioOAL_String s = pTransformationDef->m_pUpdate->getErrorText();
        LoaderMessages::Instance()->ls98PrintMessage(layTableExtract_els98, errODBCErrors_els98, s.StrPtr());
    }

    return rc;
}// ls31UpdateTransformationPackage


/*===========================================================================*
 *     END
 *===========================================================================*/
