
/*!**************************************************************************

    module      : Log_ActionCopyUpdBlob.cpp
    -------------------------------------------------------------------------

    author      : JuergenA
    responsible : UweH

    special area: Logging
    description : defines a class to handle log entries for binary large objects

    last changed: 2001-03-13

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

    copyright:    (c) 2000-2004 SAP AG


    ========== 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




*****************************************************************************/

/*===========================================================================*
*  INCLUDES                                                                  *
*============================================================================*/

#include "Logging/Log_ActionCopyUpdBlob.hpp"

#include "SAPDBCommon/SAPDB_Types.hpp"
#include "SAPDBCommon/MemoryManagement/SAPDBMem_IRawAllocator.hpp"
#include "SAPDBCommon/Tracing/SAPDBTrace_Usage.hpp" // Routine trace macros
#include "KernelCommon/Kernel_Trace.hpp"
#include "Logging/Log_ActionFileHandling.hpp"  // Log_GetFileId
#include "Logging/Log_ReadWriteActionImage.hpp"

#include "ggg00.h"
#include "hbd01.h"
#include "hbd05.h"

/*===========================================================================*
*  METHODS of Log_ActionCopyBlob                                             *
*============================================================================*/

Log_ActionCopyBlob::Log_ActionCopyBlob (const tgg00_Filename &SourceFilename,
                                        const tgg00_Filename &DestinFilename,
                                        SAPDB_Int4            DestinVersion,
                                        SAPDB_UInt4           CopyLength,
                                        SAPDB_UInt4           SourceOffset,
                                        SAPDB_UInt4           DestinOffset,
                                        SAPDB_UInt4           NewTruncatedDestinLen):
        Log_ReadWriteActionImage (Log_CopyBlob)
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionCopyBlob::Log_ActionCopyBlob", LogAction_Trace, 5);

    this->m_Entry.SourceFilename        = SourceFilename;
    this->m_Entry.DestinFilename        = DestinFilename;
    this->m_Entry.DestinVersion         = DestinVersion;
    this->m_Entry.CopyLength            = CopyLength;
    this->m_Entry.SourceOffset          = SourceOffset;
    this->m_Entry.DestinOffset          = DestinOffset;
    this->m_Entry.NewTruncatedDestinLen = NewTruncatedDestinLen;

    SAPDBTRACE_WRITELN (LogAction_Trace, 6, "DestinVers: " << DestinVersion <<
                                      ", CopyLength: " << CopyLength <<
                                      ", SourceOffset: " << SourceOffset);
    SAPDBTRACE_WRITELN (LogAction_Trace, 6, "DestinOffset" << DestinOffset <<
                                      "NewTruncLen " << NewTruncatedDestinLen);
}

//---------------------------------------------------------------------------

void Log_ActionCopyBlob::ExecuteAction (tgg00_TransContext &TransContext,
                                        tgg00_FileId       *pSourceCommandFileId,
                                        tgg00_FileId       *pDestinCommandFileId) const
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionCopyBlob::ExecuteAction", LogAction_Trace, 5);

    KERNEL_TRACE_BASIS_ERROR (TransContext.trError_gg00, LogAction_Trace, 5);

    if (e_ok != TransContext.trError_gg00) return;

    tgg00_FileId  SourceRedoFileId;
    tgg00_FileId  DestinRedoFileId;
    tgg00_FileId *pSourceExecuteFileId;
    tgg00_FileId *pDestinExecuteFileId;

    pSourceExecuteFileId =
        Log_GetFileId (this->m_Entry.SourceFilename, SourceRedoFileId, pSourceCommandFileId);

    pDestinExecuteFileId =
        Log_GetFileId (this->m_Entry.DestinFilename, DestinRedoFileId, pDestinCommandFileId);

    b05copy_bytestr (TransContext,
                     *pSourceExecuteFileId, this->m_Entry.SourceOffset+1,
                     *pDestinExecuteFileId, this->m_Entry.DestinOffset+1,
                     this->m_Entry.CopyLength,
                     this->m_Entry.DestinVersion);

    if (tfnAux_egg00 == pSourceExecuteFileId->fileTfn_gg00()) // is undo
    {
        if (e_ok == TransContext.trError_gg00)
        {
            b01pdestroy_perm_file (TransContext, *pSourceExecuteFileId);
        }
        else if (e_file_not_found == TransContext.trError_gg00)
        {
            TransContext.trError_gg00 = e_ok;

            b01filestate (TransContext, *pSourceExecuteFileId);

            if (e_file_not_found == TransContext.trError_gg00)
            {
                TransContext.trError_gg00 = e_ok;             // auxiliary file already dropped
            }
            else
            {
                if (e_ok == TransContext.trError_gg00)  // file not found was caused by
                {                                       // missing destination blob
                    b01pdestroy_perm_file (TransContext, *pSourceExecuteFileId);
                    if (e_ok == TransContext.trError_gg00)
                    {
                        TransContext.trError_gg00 = e_file_not_found;
                    }
                }
            }
        }
    }

    if (e_ok != TransContext.trError_gg00) return;

    if (this->m_Entry.NewTruncatedDestinLen > 0)
    {
        b05trunc_bytestr (TransContext, *pDestinExecuteFileId,
                          this->m_Entry.NewTruncatedDestinLen, this->m_Entry.DestinVersion);
    }
}

//---------------------------------------------------------------------------

void Log_ActionCopyBlob::ReadImagePersistent (Log_ActionImageReader &ImageReader,
        bool                  &IsOk)
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionCopyBlob::ReadImagePersistent", LogAction_Trace, 5);

    ImageReader.CopyImage (
        REINTERPRET_CAST (SAPDB_Byte*, &(this->m_Entry)),
        sizeof(this->m_Entry),
        IsOk);
}

/*===========================================================================*
*  METHODS of Log_ActionCopySameBlob                                             *
*============================================================================*/

Log_ActionCopySameBlob::Log_ActionCopySameBlob (const tgg00_Filename &BlobFilename,
        const tgg00_Filename &AuxBlobFilename,
        SAPDB_Int4            NewBlobVersion,
        SAPDB_UInt4           CopyLength,
        SAPDB_UInt4           SourceOffset,
        SAPDB_UInt4           DestinOffset):
        Log_ReadWriteActionImage (Log_CopySameBlob)
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionCopySameBlob::Log_ActionCopySameBlob", LogAction_Trace, 5);

    this->m_Entry.BlobFilename    = BlobFilename;
    this->m_Entry.AuxBlobFilename = AuxBlobFilename;
    this->m_Entry.NewBlobVersion  = NewBlobVersion;
    this->m_Entry.CopyLength      = CopyLength;
    this->m_Entry.SourceOffset    = SourceOffset;
    this->m_Entry.DestinOffset    = DestinOffset;

    SAPDBTRACE_WRITELN (LogAction_Trace, 6, "NewBlobVers: " << NewBlobVersion <<
                                      "CopyLength: " << CopyLength);
    SAPDBTRACE_WRITELN (LogAction_Trace, 6, "SourceOffset: " << SourceOffset <<
                                      "DestinOffset: " << DestinOffset);
}

//---------------------------------------------------------------------------

void Log_ActionCopySameBlob::Execute (tgg00_TransContext &TransContext) const
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionCopySameBlob::Execute", LogAction_Trace, 5);

    KERNEL_TRACE_BASIS_ERROR (TransContext.trError_gg00, LogAction_Trace, 5);

    if (e_ok != TransContext.trError_gg00) return;

    tgg00_FileId  BlobId;
    tgg00_FileId  AuxBlobId;
    tgg00_FileId *pDummyFileId;
    SAPDB_Int4    CurrBlobVersion      = 0;
    SAPDB_Int4    CurrAuxBlobVersion   = 0;
    SAPDB_Int4    CurrAuxBlobLength    = 0;
    SAPDB_Int4    CurrAuxBlobPages     = 0;
    SAPDB_UInt4   AbsCurrAuxBlobLength = 0;


    pDummyFileId = Log_GetFileId (this->m_Entry.BlobFilename,    BlobId,    NULL);
    pDummyFileId = Log_GetFileId (this->m_Entry.AuxBlobFilename, AuxBlobId, NULL);

    b05get_str_version (TransContext, BlobId, CurrBlobVersion);

    if (e_ok != TransContext.trError_gg00) return;

    if (CurrBlobVersion != this->m_Entry.NewBlobVersion)
    {
        b01bcreate_bytestr (TransContext, AuxBlobId);

        if (e_duplicate_filename == TransContext.trError_gg00)
        {
            b05length_bytestr (TransContext, AuxBlobId, CurrAuxBlobLength, 
                CurrAuxBlobPages ,CurrAuxBlobVersion);
        }

        if (e_ok != TransContext.trError_gg00) return;

        AbsCurrAuxBlobLength = abs(CurrAuxBlobLength);

        if (AbsCurrAuxBlobLength < this->m_Entry.CopyLength)
        {
            b05copy_bytestr (TransContext,
                             BlobId, this->m_Entry.SourceOffset+1,
                             AuxBlobId, 1,
                             this->m_Entry.CopyLength,
                             this->m_Entry.NewBlobVersion);

            if (e_ok != TransContext.trError_gg00) return;
        }

        b05copy_bytestr (TransContext,
                         AuxBlobId, 1,
                         BlobId, this->m_Entry.DestinOffset+1,
                         this->m_Entry.CopyLength,
                         this->m_Entry.NewBlobVersion);

        if (e_ok != TransContext.trError_gg00) return;
    }

    b01pdestroy_perm_file (TransContext, AuxBlobId);

    if (e_file_not_found == TransContext.trError_gg00) TransContext.trError_gg00 = e_ok;
}

//---------------------------------------------------------------------------

void Log_ActionCopySameBlob::ExecuteAction (tgg00_TransContext &TransContext,
        tgg00_FileId       &BlobId,
        tgg00_FileId       &AuxBlobId) const
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionCopySameBlob::ExecuteAction", LogAction_Trace, 5);

    KERNEL_TRACE_BASIS_ERROR (TransContext.trError_gg00, LogAction_Trace, 5);

    b01bcreate_bytestr (TransContext, AuxBlobId);

    if (e_ok != TransContext.trError_gg00) return;

    b05copy_bytestr (TransContext,
                     BlobId, this->m_Entry.SourceOffset+1,
                     AuxBlobId, 1,
                     this->m_Entry.CopyLength,
                     this->m_Entry.NewBlobVersion);

    if (e_ok != TransContext.trError_gg00) return;

    b05copy_bytestr (TransContext,
                     AuxBlobId, 1,
                     BlobId, this->m_Entry.DestinOffset+1,
                     this->m_Entry.CopyLength,
                     this->m_Entry.NewBlobVersion);

    if (e_ok != TransContext.trError_gg00) return;

    b01pdestroy_perm_file (TransContext, AuxBlobId);
}

//---------------------------------------------------------------------------

void Log_ActionCopySameBlob::ReadImagePersistent (Log_ActionImageReader &ImageReader,
        bool                  &IsOk)
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionCopySameBlob::ReadImagePersistent", LogAction_Trace, 5);

    ImageReader.CopyImage (
        REINTERPRET_CAST (SAPDB_Byte*, &(this->m_Entry)),
        sizeof(this->m_Entry),
        IsOk);
}


/*===========================================================================*
*  METHODS of Log_ActionExpandBlob                                           *
*============================================================================*/

Log_ActionExpandBlob::Log_ActionExpandBlob (const tgg00_Filename &BlobFilename,
        SAPDB_UInt4           NewBlobLength,
        SAPDB_Byte            ExpandByte):
        Log_ReadWriteActionImage (Log_ExpandBlob)
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionExpandBlob::Log_ActionExpandBlob", LogAction_Trace, 5);

    this->m_Entry.BlobFilename  = BlobFilename;
    this->m_Entry.NewBlobLength = NewBlobLength;
    this->m_Entry.ExpandByte    = ExpandByte;

    SAPDBTRACE_WRITELN (LogAction_Trace, 6, "NewBlobLength: " << NewBlobLength <<
                                      ", ExpandByte: " << ExpandByte);
}

//---------------------------------------------------------------------------

void Log_ActionExpandBlob::ExecuteAction (tgg00_TransContext &TransContext,
        tgg00_FileId       *pCommandBlobFileId) const
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionExpandBlob::ExecuteAction", LogAction_Trace, 5);

    KERNEL_TRACE_BASIS_ERROR (TransContext.trError_gg00, LogAction_Trace, 5);

    if (e_ok != TransContext.trError_gg00) return;

    tgg00_FileId  RedoBlobFileId;
    tgg00_FileId *pExecuteBlobFileId;

    pExecuteBlobFileId =
        Log_GetFileId (this->m_Entry.BlobFilename, RedoBlobFileId, pCommandBlobFileId);

    b05expand_bytestr (TransContext, *pExecuteBlobFileId, this->m_Entry.NewBlobLength,
                       this->m_Entry.ExpandByte, NIL_STR_VERSION_GG00);
}

//---------------------------------------------------------------------------

void Log_ActionExpandBlob::ReadImagePersistent (Log_ActionImageReader &ImageReader,
        bool                  &IsOk)
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionExpandBlob::ReadImagePersistent", LogAction_Trace, 5);

    ImageReader.CopyImage (
        REINTERPRET_CAST (SAPDB_Byte*, &(this->m_Entry)),
        sizeof(this->m_Entry),
        IsOk);
}


/*===========================================================================*
*  METHODS of Log_ActionTruncateBlob                                           *
*============================================================================*/

Log_ActionTruncateBlob::Log_ActionTruncateBlob (const tgg00_Filename &BlobFilename,
        SAPDB_Int4            BlobVersion,
        SAPDB_UInt4           NewTruncatedBlobLen):
        Log_ReadWriteActionImage (Log_TruncateBlob)
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionTruncateBlob::Log_ActionTruncateBlob", LogAction_Trace, 5);

    this->m_Entry.BlobFilename        = BlobFilename;
    this->m_Entry.BlobVersion         = BlobVersion;
    this->m_Entry.NewTruncatedBlobLen = NewTruncatedBlobLen;

    SAPDBTRACE_WRITELN (LogAction_Trace, 6, "BlobVersion: " << BlobVersion <<
                                      ", NewTruncatedBlobLen: " << NewTruncatedBlobLen);
}

//---------------------------------------------------------------------------

void Log_ActionTruncateBlob::ExecuteAction (tgg00_TransContext &TransContext,
        tgg00_FileId       *pCommandBlobFileId) const
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionTruncateBlob::ExecuteAction", LogAction_Trace, 5);

    KERNEL_TRACE_BASIS_ERROR (TransContext.trError_gg00, LogAction_Trace, 5);

    if (e_ok != TransContext.trError_gg00) return;

    tgg00_FileId  RedoBlobFileId;
    tgg00_FileId *pExecuteBlobFileId;

    pExecuteBlobFileId =
        Log_GetFileId (this->m_Entry.BlobFilename, RedoBlobFileId, pCommandBlobFileId);

    b05trunc_bytestr (
        TransContext,
        *pExecuteBlobFileId,
        this->m_Entry.NewTruncatedBlobLen,
        this->m_Entry.BlobVersion);
}

//---------------------------------------------------------------------------

void Log_ActionTruncateBlob::ReadImagePersistent (Log_ActionImageReader &ImageReader,
        bool                  &IsOk)
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionTruncateBlob::ReadImagePersistent", LogAction_Trace, 5);

    ImageReader.CopyImage (
        REINTERPRET_CAST (SAPDB_Byte*, &(this->m_Entry)),
        sizeof(this->m_Entry),
        IsOk);
}


/*===========================================================================*
*  METHODS of Log_ActionUpdateBlob                                           *
*============================================================================*/

Log_ActionUpdateBlob::Log_ActionUpdateBlob (const tgg00_Filename &BlobFilename,
        SAPDB_UInt4           InsertOffset,
        const SAPDB_Byte*     pBuf,
        SAPDB_UInt4           BufLength):
        Log_ReadWriteActionImage (Log_UpdateBlob),
        m_pBuf                   (pBuf),
        m_pBufForRead            (NULL),
        m_pBufAllocator          (NULL)
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionUpdateBlob::Log_ActionUpdateBlob", LogAction_Trace, 5);

    this->m_EntryHeader.ImageLength  =
        Log_AlignedImageLen (sizeof(this->m_EntryHeader)) + Log_AlignedImageLen (BufLength);
    this->m_EntryHeader.BufLength    = BufLength;
    this->m_EntryHeader.InsertOffset = InsertOffset;
    this->m_EntryHeader.BlobFilename = BlobFilename;

    SAPDBTRACE_WRITELN (LogAction_Trace, 6, "ImageLength: " << m_EntryHeader.ImageLength <<
                                      ", InsertOffset: " << InsertOffset <<
                                      ", BufLength: " << BufLength);
    SAPDBTRACE_IF      (LogAction_Trace, 6, Kernel_TraceBuffer(pBuf, BufLength));
}
//---------------------------------------------------------------------------

Log_ActionUpdateBlob::~Log_ActionUpdateBlob ()
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionUpdateBlob::~Log_ActionUpdateBlob", LogAction_Trace, 5);
    if (NULL != this->m_pBufAllocator)
    {
        this->m_pBufAllocator->Deallocate (this->m_pBufForRead);
        this->m_pBufForRead = NULL;
    }
}

//---------------------------------------------------------------------------

void Log_ActionUpdateBlob::ExecuteAction (tgg00_TransContext &TransContext,
        tgg00_FileId       *pCommandBlobFileId) const
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionUpdateBlob::ExecuteAction", LogAction_Trace, 5);

    KERNEL_TRACE_BASIS_ERROR (TransContext.trError_gg00, LogAction_Trace, 5);

    if (e_ok != TransContext.trError_gg00) return;

    tgg00_FileId  RedoBlobFileId;
    tgg00_FileId *pExecuteBlobFileId;

    pExecuteBlobFileId =
        Log_GetFileId (this->m_EntryHeader.BlobFilename, RedoBlobFileId, pCommandBlobFileId);

    b05write_bytestr (TransContext,
                      *pExecuteBlobFileId,
                      this->m_EntryHeader.InsertOffset+1,
                      this->m_EntryHeader.BufLength,
                      this->m_EntryHeader.BufLength,
                      this->m_pBuf, 1, NIL_STR_VERSION_GG00);
}

//---------------------------------------------------------------------------

void Log_ActionUpdateBlob::ReadImagePersistent (Log_ActionImageReader &ImageReader,
        bool                  &IsOk)
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionUpdateBlob::ReadImagePersistent", LogAction_Trace, 5);

    ImageReader.CopyImage (
        REINTERPRET_CAST (SAPDB_Byte*, &(this->m_EntryHeader)),
        sizeof(this->m_EntryHeader),
        IsOk);

    if (! IsOk) return;

    ImageReader.PersistentRead (
        this->m_pBufForRead,
        this->m_EntryHeader.BufLength,
        this->m_pBufAllocator,
        IsOk);

    if (IsOk) this->m_pBuf = this->m_pBufForRead;
}

//---------------------------------------------------------------------------

void Log_ActionUpdateBlob::WriteImagePersistent (Log_ActionImageWriter &ImageWriter,
        bool                  &IsOk)       const
{
    SAPDBTRACE_METHOD_DEBUG ("Log_ActionUpdateBlob::WriteImagePersistent", LogAction_Trace, 5);

    ImageWriter.PersistentWrite (&m_EntryHeader, sizeof (m_EntryHeader), IsOk);
    if ( ! IsOk )
        return;
    ImageWriter.PersistentWrite (this->m_pBuf, this->m_EntryHeader.BufLength, IsOk);
    if ( ! IsOk )
        return;

}

/*===========================================================================*
*  END OF CODE                                                               *
*============================================================================*/
